Mercurial > hg > octave-terminal
changeset 15574:6ea536cb7360 classdef
maint: periodic merge of default to classdef
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Thu, 01 Nov 2012 15:01:20 -0400 |
parents | 947cf10c94da (current diff) 859c8bf6d134 (diff) |
children | |
files | autogen.sh build-aux/bootstrap build-aux/bootstrap.conf doc/faq/Makefile.am doc/faq/OctaveFAQ.texi libcruft/Makefile.am libcruft/amos/README libcruft/amos/cacai.f libcruft/amos/cacon.f libcruft/amos/cairy.f libcruft/amos/casyi.f libcruft/amos/cbesh.f libcruft/amos/cbesi.f libcruft/amos/cbesj.f libcruft/amos/cbesk.f libcruft/amos/cbesy.f libcruft/amos/cbinu.f libcruft/amos/cbiry.f libcruft/amos/cbknu.f libcruft/amos/cbuni.f libcruft/amos/cbunk.f libcruft/amos/ckscl.f libcruft/amos/cmlri.f libcruft/amos/crati.f libcruft/amos/cs1s2.f libcruft/amos/cseri.f libcruft/amos/cshch.f libcruft/amos/cuchk.f libcruft/amos/cunhj.f libcruft/amos/cuni1.f libcruft/amos/cuni2.f libcruft/amos/cunik.f libcruft/amos/cunk1.f libcruft/amos/cunk2.f libcruft/amos/cuoik.f libcruft/amos/cwrsk.f libcruft/amos/dgamln.f libcruft/amos/gamln.f libcruft/amos/module.mk libcruft/amos/xzabs.f libcruft/amos/xzexp.f libcruft/amos/xzlog.f libcruft/amos/xzsqrt.f libcruft/amos/zacai.f libcruft/amos/zacon.f libcruft/amos/zairy.f libcruft/amos/zasyi.f libcruft/amos/zbesh.f libcruft/amos/zbesi.f libcruft/amos/zbesj.f libcruft/amos/zbesk.f libcruft/amos/zbesy.f libcruft/amos/zbinu.f libcruft/amos/zbiry.f libcruft/amos/zbknu.f libcruft/amos/zbuni.f libcruft/amos/zbunk.f libcruft/amos/zdiv.f libcruft/amos/zkscl.f libcruft/amos/zmlri.f libcruft/amos/zmlt.f libcruft/amos/zrati.f libcruft/amos/zs1s2.f libcruft/amos/zseri.f libcruft/amos/zshch.f libcruft/amos/zuchk.f libcruft/amos/zunhj.f libcruft/amos/zuni1.f libcruft/amos/zuni2.f libcruft/amos/zunik.f libcruft/amos/zunk1.f libcruft/amos/zunk2.f libcruft/amos/zuoik.f libcruft/amos/zwrsk.f libcruft/blas-xtra/cconv2.f libcruft/blas-xtra/cdotc3.f libcruft/blas-xtra/cmatm3.f libcruft/blas-xtra/csconv2.f libcruft/blas-xtra/dconv2.f libcruft/blas-xtra/ddot3.f libcruft/blas-xtra/dmatm3.f libcruft/blas-xtra/module.mk libcruft/blas-xtra/sconv2.f libcruft/blas-xtra/sdot3.f libcruft/blas-xtra/smatm3.f libcruft/blas-xtra/xcdotc.f libcruft/blas-xtra/xcdotu.f libcruft/blas-xtra/xddot.f libcruft/blas-xtra/xdnrm2.f libcruft/blas-xtra/xdznrm2.f libcruft/blas-xtra/xerbla.f libcruft/blas-xtra/xscnrm2.f libcruft/blas-xtra/xsdot.f libcruft/blas-xtra/xsnrm2.f libcruft/blas-xtra/xzdotc.f libcruft/blas-xtra/xzdotu.f libcruft/blas-xtra/zconv2.f libcruft/blas-xtra/zdconv2.f libcruft/blas-xtra/zdotc3.f libcruft/blas-xtra/zmatm3.f libcruft/daspk/datv.f libcruft/daspk/dcnst0.f libcruft/daspk/dcnstr.f libcruft/daspk/ddasic.f libcruft/daspk/ddasid.f libcruft/daspk/ddasik.f libcruft/daspk/ddaspk.f libcruft/daspk/ddstp.f libcruft/daspk/ddwnrm.f libcruft/daspk/dfnrmd.f libcruft/daspk/dfnrmk.f libcruft/daspk/dhels.f libcruft/daspk/dheqr.f libcruft/daspk/dinvwt.f libcruft/daspk/dlinsd.f libcruft/daspk/dlinsk.f libcruft/daspk/dmatd.f libcruft/daspk/dnedd.f libcruft/daspk/dnedk.f libcruft/daspk/dnsd.f libcruft/daspk/dnsid.f libcruft/daspk/dnsik.f libcruft/daspk/dnsk.f libcruft/daspk/dorth.f libcruft/daspk/dslvd.f libcruft/daspk/dslvk.f libcruft/daspk/dspigm.f libcruft/daspk/dyypnw.f libcruft/daspk/module.mk libcruft/dasrt/ddasrt.f libcruft/dasrt/drchek.f libcruft/dasrt/droots.f libcruft/dasrt/module.mk libcruft/dassl/ddaini.f libcruft/dassl/ddajac.f libcruft/dassl/ddanrm.f libcruft/dassl/ddaslv.f libcruft/dassl/ddassl.f libcruft/dassl/ddastp.f libcruft/dassl/ddatrp.f libcruft/dassl/ddawts.f libcruft/dassl/module.mk libcruft/fftpack/cfftb.f libcruft/fftpack/cfftb1.f libcruft/fftpack/cfftf.f libcruft/fftpack/cfftf1.f libcruft/fftpack/cffti.f libcruft/fftpack/cffti1.f libcruft/fftpack/fftpack.doc libcruft/fftpack/module.mk libcruft/fftpack/passb.f libcruft/fftpack/passb2.f libcruft/fftpack/passb3.f libcruft/fftpack/passb4.f libcruft/fftpack/passb5.f libcruft/fftpack/passf.f libcruft/fftpack/passf2.f libcruft/fftpack/passf3.f libcruft/fftpack/passf4.f libcruft/fftpack/passf5.f libcruft/fftpack/zfftb.f libcruft/fftpack/zfftb1.f libcruft/fftpack/zfftf.f libcruft/fftpack/zfftf1.f libcruft/fftpack/zffti.f libcruft/fftpack/zffti1.f libcruft/fftpack/zpassb.f libcruft/fftpack/zpassb2.f libcruft/fftpack/zpassb3.f libcruft/fftpack/zpassb4.f libcruft/fftpack/zpassb5.f libcruft/fftpack/zpassf.f libcruft/fftpack/zpassf2.f libcruft/fftpack/zpassf3.f libcruft/fftpack/zpassf4.f libcruft/fftpack/zpassf5.f libcruft/lapack-xtra/crsf2csf.f libcruft/lapack-xtra/module.mk libcruft/lapack-xtra/xclange.f libcruft/lapack-xtra/xdlamch.f libcruft/lapack-xtra/xdlange.f libcruft/lapack-xtra/xilaenv.f libcruft/lapack-xtra/xslamch.f libcruft/lapack-xtra/xslange.f libcruft/lapack-xtra/xzlange.f libcruft/lapack-xtra/zrsf2csf.f libcruft/link-deps.mk libcruft/misc/blaswrap.c libcruft/misc/cquit.c libcruft/misc/d1mach-tst.for libcruft/misc/d1mach.f libcruft/misc/f77-extern.cc libcruft/misc/f77-fcn.c libcruft/misc/f77-fcn.h libcruft/misc/i1mach.f libcruft/misc/lo-error.c libcruft/misc/lo-error.h libcruft/misc/module.mk libcruft/misc/quit.cc libcruft/misc/quit.h libcruft/misc/r1mach.f libcruft/mkf77def.in libcruft/odepack/cfode.f libcruft/odepack/dlsode.f libcruft/odepack/ewset.f libcruft/odepack/intdy.f libcruft/odepack/module.mk libcruft/odepack/prepj.f libcruft/odepack/scfode.f libcruft/odepack/sewset.f libcruft/odepack/sintdy.f libcruft/odepack/slsode.f libcruft/odepack/solsy.f libcruft/odepack/sprepj.f libcruft/odepack/ssolsy.f libcruft/odepack/sstode.f libcruft/odepack/stode.f libcruft/odepack/svnorm.f libcruft/odepack/vnorm.f libcruft/ordered-qz/README libcruft/ordered-qz/dsubsp.f libcruft/ordered-qz/exchqz.f libcruft/ordered-qz/module.mk libcruft/ordered-qz/sexchqz.f libcruft/ordered-qz/ssubsp.f libcruft/quadpack/dqagi.f libcruft/quadpack/dqagie.f libcruft/quadpack/dqagp.f libcruft/quadpack/dqagpe.f libcruft/quadpack/dqelg.f libcruft/quadpack/dqk15i.f libcruft/quadpack/dqk21.f libcruft/quadpack/dqpsrt.f libcruft/quadpack/module.mk libcruft/quadpack/qagi.f libcruft/quadpack/qagie.f libcruft/quadpack/qagp.f libcruft/quadpack/qagpe.f libcruft/quadpack/qelg.f libcruft/quadpack/qk15i.f libcruft/quadpack/qk21.f libcruft/quadpack/qpsrt.f libcruft/quadpack/xerror.f libcruft/ranlib/Basegen.doc libcruft/ranlib/HOWTOGET libcruft/ranlib/README libcruft/ranlib/advnst.f libcruft/ranlib/genbet.f libcruft/ranlib/genchi.f libcruft/ranlib/genexp.f libcruft/ranlib/genf.f libcruft/ranlib/gengam.f libcruft/ranlib/genmn.f libcruft/ranlib/genmul.f libcruft/ranlib/gennch.f libcruft/ranlib/gennf.f libcruft/ranlib/gennor.f libcruft/ranlib/genprm.f libcruft/ranlib/genunf.f libcruft/ranlib/getcgn.f libcruft/ranlib/getsd.f libcruft/ranlib/ignbin.f libcruft/ranlib/ignlgi.f libcruft/ranlib/ignnbn.f libcruft/ranlib/ignpoi.f libcruft/ranlib/ignuin.f libcruft/ranlib/initgn.f libcruft/ranlib/inrgcm.f libcruft/ranlib/lennob.f libcruft/ranlib/mltmod.f libcruft/ranlib/module.mk libcruft/ranlib/phrtsd.f libcruft/ranlib/qrgnin.f libcruft/ranlib/randlib.chs libcruft/ranlib/randlib.fdoc libcruft/ranlib/ranf.f libcruft/ranlib/setall.f libcruft/ranlib/setant.f libcruft/ranlib/setgmn.f libcruft/ranlib/setsd.f libcruft/ranlib/sexpo.f libcruft/ranlib/sgamma.f libcruft/ranlib/snorm.f libcruft/ranlib/tstbot.for libcruft/ranlib/tstgmn.for libcruft/ranlib/tstmid.for libcruft/ranlib/wrap.f libcruft/slatec-err/fdump.f libcruft/slatec-err/ixsav.f libcruft/slatec-err/j4save.f libcruft/slatec-err/module.mk libcruft/slatec-err/xerclr.f libcruft/slatec-err/xercnt.f libcruft/slatec-err/xerhlt.f libcruft/slatec-err/xermsg.f libcruft/slatec-err/xerprn.f libcruft/slatec-err/xerrwd.f libcruft/slatec-err/xersve.f libcruft/slatec-err/xgetf.f libcruft/slatec-err/xgetua.f libcruft/slatec-err/xsetf.f libcruft/slatec-err/xsetua.f libcruft/slatec-fn/acosh.f libcruft/slatec-fn/albeta.f libcruft/slatec-fn/algams.f libcruft/slatec-fn/alngam.f libcruft/slatec-fn/alnrel.f libcruft/slatec-fn/asinh.f libcruft/slatec-fn/atanh.f libcruft/slatec-fn/betai.f libcruft/slatec-fn/csevl.f libcruft/slatec-fn/d9gmit.f libcruft/slatec-fn/d9lgic.f libcruft/slatec-fn/d9lgit.f libcruft/slatec-fn/d9lgmc.f libcruft/slatec-fn/dacosh.f libcruft/slatec-fn/dasinh.f libcruft/slatec-fn/datanh.f libcruft/slatec-fn/dbetai.f libcruft/slatec-fn/dcsevl.f libcruft/slatec-fn/derf.f libcruft/slatec-fn/derfc.in.f libcruft/slatec-fn/dgami.f libcruft/slatec-fn/dgamit.f libcruft/slatec-fn/dgamlm.f libcruft/slatec-fn/dgamma.f libcruft/slatec-fn/dgamr.f libcruft/slatec-fn/dlbeta.f libcruft/slatec-fn/dlgams.f libcruft/slatec-fn/dlngam.f libcruft/slatec-fn/dlnrel.f libcruft/slatec-fn/dpchim.f libcruft/slatec-fn/dpchst.f libcruft/slatec-fn/erf.f libcruft/slatec-fn/erfc.in.f libcruft/slatec-fn/gami.f libcruft/slatec-fn/gamit.f libcruft/slatec-fn/gamlim.f libcruft/slatec-fn/gamma.f libcruft/slatec-fn/gamr.f libcruft/slatec-fn/initds.f libcruft/slatec-fn/inits.f libcruft/slatec-fn/module.mk libcruft/slatec-fn/pchim.f libcruft/slatec-fn/pchst.f libcruft/slatec-fn/r9gmit.f libcruft/slatec-fn/r9lgic.f libcruft/slatec-fn/r9lgit.f libcruft/slatec-fn/r9lgmc.f libcruft/slatec-fn/xacosh.f libcruft/slatec-fn/xasinh.f libcruft/slatec-fn/xatanh.f libcruft/slatec-fn/xbetai.f libcruft/slatec-fn/xdacosh.f libcruft/slatec-fn/xdasinh.f libcruft/slatec-fn/xdatanh.f libcruft/slatec-fn/xdbetai.f libcruft/slatec-fn/xderf.f libcruft/slatec-fn/xderfc.f libcruft/slatec-fn/xdgami.f libcruft/slatec-fn/xdgamit.f libcruft/slatec-fn/xdgamma.f libcruft/slatec-fn/xerf.f libcruft/slatec-fn/xerfc.f libcruft/slatec-fn/xgamma.f libcruft/slatec-fn/xgmainc.f libcruft/slatec-fn/xsgmainc.f libgui/src/Makefile.am libgui/src/link-deps.mk libgui/src/octave-adapter/octave-event-observer.h libgui/src/octave-adapter/octave-event.cc libgui/src/octave-adapter/octave-event.h libinterp/Makefile.am libinterp/octave-value/module.mk libinterp/octave-value/ov.cc libinterp/octave.cc libinterp/parse-tree/lex.ll libinterp/parse-tree/module.mk libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-id.h liboctave/Array-C.cc liboctave/Array-b.cc liboctave/Array-ch.cc liboctave/Array-d.cc liboctave/Array-f.cc liboctave/Array-fC.cc liboctave/Array-i.cc liboctave/Array-idx-vec.cc liboctave/Array-s.cc liboctave/Array-str.cc liboctave/Array-util.cc liboctave/Array-util.h liboctave/Array-voidp.cc liboctave/Array.cc liboctave/Array.h liboctave/Array2.h liboctave/Array3.h liboctave/ArrayN.h liboctave/CColVector.cc liboctave/CColVector.h liboctave/CDiagMatrix.cc liboctave/CDiagMatrix.h liboctave/CMatrix.cc liboctave/CMatrix.h liboctave/CNDArray.cc liboctave/CNDArray.h liboctave/CRowVector.cc liboctave/CRowVector.h liboctave/CSparse.cc liboctave/CSparse.h liboctave/CmplxAEPBAL.cc liboctave/CmplxAEPBAL.h liboctave/CmplxCHOL.cc liboctave/CmplxCHOL.h liboctave/CmplxGEPBAL.cc liboctave/CmplxGEPBAL.h liboctave/CmplxHESS.cc liboctave/CmplxHESS.h liboctave/CmplxLU.cc liboctave/CmplxLU.h liboctave/CmplxQR.cc liboctave/CmplxQR.h liboctave/CmplxQRP.cc liboctave/CmplxQRP.h liboctave/CmplxSCHUR.cc liboctave/CmplxSCHUR.h liboctave/CmplxSVD.cc liboctave/CmplxSVD.h liboctave/CollocWt.cc liboctave/CollocWt.h liboctave/DAE.h liboctave/DAEFunc.h liboctave/DAERT.h liboctave/DAERTFunc.h liboctave/DASPK-opts.in liboctave/DASPK.cc liboctave/DASPK.h liboctave/DASRT-opts.in liboctave/DASRT.cc liboctave/DASRT.h liboctave/DASSL-opts.in liboctave/DASSL.cc liboctave/DASSL.h liboctave/DET.h liboctave/DiagArray2.cc liboctave/DiagArray2.h liboctave/EIG.cc liboctave/EIG.h liboctave/LSODE-opts.in liboctave/LSODE.cc liboctave/LSODE.h liboctave/MArray-C.cc liboctave/MArray-d.cc liboctave/MArray-decl.h liboctave/MArray-defs.h liboctave/MArray-f.cc liboctave/MArray-fC.cc liboctave/MArray-i.cc liboctave/MArray-s.cc liboctave/MArray.cc liboctave/MArray.h liboctave/MArray2.h liboctave/MArrayN.h liboctave/MDiagArray2.cc liboctave/MDiagArray2.h liboctave/MSparse-C.cc liboctave/MSparse-d.cc liboctave/MSparse-defs.h liboctave/MSparse.cc liboctave/MSparse.h liboctave/Matrix.h liboctave/MatrixType.cc liboctave/MatrixType.h liboctave/ODE.h liboctave/ODEFunc.h liboctave/ODES.cc liboctave/ODES.h liboctave/ODESFunc.h liboctave/PermMatrix.cc liboctave/PermMatrix.h liboctave/Quad-opts.in liboctave/Quad.cc liboctave/Quad.h liboctave/Range.cc liboctave/Range.h liboctave/Sparse-C.cc liboctave/Sparse-b.cc liboctave/Sparse-d.cc liboctave/Sparse-diag-op-defs.h liboctave/Sparse-op-defs.h liboctave/Sparse-perm-op-defs.h liboctave/Sparse.cc liboctave/Sparse.h liboctave/SparseCmplxCHOL.cc liboctave/SparseCmplxCHOL.h liboctave/SparseCmplxLU.cc liboctave/SparseCmplxLU.h liboctave/SparseCmplxQR.cc liboctave/SparseCmplxQR.h liboctave/SparseQR.cc liboctave/SparseQR.h liboctave/SparsedbleCHOL.cc liboctave/SparsedbleCHOL.h liboctave/SparsedbleLU.cc liboctave/SparsedbleLU.h liboctave/base-aepbal.h liboctave/base-dae.h liboctave/base-de.h liboctave/base-list.h liboctave/base-lu.cc liboctave/base-lu.h liboctave/base-min.h liboctave/base-qr.cc liboctave/base-qr.h liboctave/boolMatrix.cc liboctave/boolMatrix.h liboctave/boolNDArray.cc liboctave/boolNDArray.h liboctave/boolSparse.cc liboctave/boolSparse.h liboctave/bsxfun-decl.h liboctave/bsxfun-defs.cc liboctave/bsxfun.h liboctave/byte-swap.h liboctave/caseless-str.h liboctave/chMatrix.cc liboctave/chMatrix.h liboctave/chNDArray.cc liboctave/chNDArray.h liboctave/cmd-edit.cc liboctave/cmd-edit.h liboctave/cmd-hist.cc liboctave/cmd-hist.h liboctave/config-ops.sh liboctave/dColVector.cc liboctave/dColVector.h liboctave/dDiagMatrix.cc liboctave/dDiagMatrix.h liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/dRowVector.cc liboctave/dRowVector.h liboctave/dSparse.cc liboctave/dSparse.h liboctave/data-conv.cc liboctave/data-conv.h liboctave/dbleAEPBAL.cc liboctave/dbleAEPBAL.h liboctave/dbleCHOL.cc liboctave/dbleCHOL.h liboctave/dbleGEPBAL.cc liboctave/dbleGEPBAL.h liboctave/dbleHESS.cc liboctave/dbleHESS.h liboctave/dbleLU.cc liboctave/dbleLU.h liboctave/dbleQR.cc liboctave/dbleQR.h liboctave/dbleQRP.cc liboctave/dbleQRP.h liboctave/dbleSCHUR.cc liboctave/dbleSCHUR.h liboctave/dbleSVD.cc liboctave/dbleSVD.h liboctave/dim-vector.cc liboctave/dim-vector.h liboctave/dir-ops.cc liboctave/dir-ops.h liboctave/eigs-base.cc liboctave/f2c-main.c liboctave/fCColVector.cc liboctave/fCColVector.h liboctave/fCDiagMatrix.cc liboctave/fCDiagMatrix.h liboctave/fCMatrix.cc liboctave/fCMatrix.h liboctave/fCNDArray.cc liboctave/fCNDArray.h liboctave/fCRowVector.cc liboctave/fCRowVector.h liboctave/fCmplxAEPBAL.cc liboctave/fCmplxAEPBAL.h liboctave/fCmplxCHOL.cc liboctave/fCmplxCHOL.h liboctave/fCmplxGEPBAL.cc liboctave/fCmplxGEPBAL.h liboctave/fCmplxHESS.cc liboctave/fCmplxHESS.h liboctave/fCmplxLU.cc liboctave/fCmplxLU.h liboctave/fCmplxQR.cc liboctave/fCmplxQR.h liboctave/fCmplxQRP.cc liboctave/fCmplxQRP.h liboctave/fCmplxSCHUR.cc liboctave/fCmplxSCHUR.h liboctave/fCmplxSVD.cc liboctave/fCmplxSVD.h liboctave/fColVector.cc liboctave/fColVector.h liboctave/fDiagMatrix.cc liboctave/fDiagMatrix.h liboctave/fEIG.cc liboctave/fEIG.h liboctave/fMatrix.cc liboctave/fMatrix.h liboctave/fNDArray.cc liboctave/fNDArray.h liboctave/fRowVector.cc liboctave/fRowVector.h liboctave/file-ops.cc liboctave/file-ops.h liboctave/file-stat.cc liboctave/file-stat.h liboctave/floatAEPBAL.cc liboctave/floatAEPBAL.h liboctave/floatCHOL.cc liboctave/floatCHOL.h liboctave/floatGEPBAL.cc liboctave/floatGEPBAL.h liboctave/floatHESS.cc liboctave/floatHESS.h liboctave/floatLU.cc liboctave/floatLU.h liboctave/floatQR.cc liboctave/floatQR.h liboctave/floatQRP.cc liboctave/floatQRP.h liboctave/floatSCHUR.cc liboctave/floatSCHUR.h liboctave/floatSVD.cc liboctave/floatSVD.h liboctave/functor.h liboctave/glob-match.cc liboctave/glob-match.h liboctave/idx-vector.cc liboctave/idx-vector.h liboctave/int16NDArray.cc liboctave/int16NDArray.h liboctave/int32NDArray.cc liboctave/int32NDArray.h liboctave/int64NDArray.cc liboctave/int64NDArray.h liboctave/int8NDArray.cc liboctave/int8NDArray.h liboctave/intNDArray.cc liboctave/intNDArray.h liboctave/kpse.cc liboctave/lo-array-gripes.cc liboctave/lo-array-gripes.h liboctave/lo-cieee.c liboctave/lo-cutils.c liboctave/lo-cutils.h liboctave/lo-ieee.cc liboctave/lo-ieee.h liboctave/lo-macros.h liboctave/lo-mappers.cc liboctave/lo-mappers.h liboctave/lo-math.h liboctave/lo-specfun.cc liboctave/lo-specfun.h liboctave/lo-sysdep.cc liboctave/lo-sysdep.h liboctave/lo-traits.h liboctave/lo-utils.cc liboctave/lo-utils.h liboctave/mach-info.cc liboctave/mach-info.h liboctave/mk-ops.awk liboctave/mx-base.h liboctave/mx-defs.h liboctave/mx-ext.h liboctave/mx-inlines.cc liboctave/mx-op-decl.h liboctave/mx-op-defs.h liboctave/mx-ops liboctave/oct-alloc.cc liboctave/oct-alloc.h liboctave/oct-binmap.h liboctave/oct-cmplx.h liboctave/oct-convn.cc liboctave/oct-convn.h liboctave/oct-env.cc liboctave/oct-env.h liboctave/oct-fftw.cc liboctave/oct-fftw.h liboctave/oct-glob.cc liboctave/oct-glob.h liboctave/oct-group.cc liboctave/oct-group.h liboctave/oct-inttypes.cc liboctave/oct-inttypes.h liboctave/oct-locbuf.cc liboctave/oct-locbuf.h liboctave/oct-md5.cc liboctave/oct-md5.h liboctave/oct-mem.h liboctave/oct-mutex.cc liboctave/oct-mutex.h liboctave/oct-norm.cc liboctave/oct-norm.h liboctave/oct-openmp.h liboctave/oct-passwd.cc liboctave/oct-passwd.h liboctave/oct-rand.cc liboctave/oct-rand.h liboctave/oct-refcount.h liboctave/oct-rl-edit.c liboctave/oct-rl-edit.h liboctave/oct-rl-hist.c liboctave/oct-rl-hist.h liboctave/oct-shlib.cc liboctave/oct-shlib.h liboctave/oct-sort.cc liboctave/oct-sort.h liboctave/oct-sparse.h liboctave/oct-spparms.cc liboctave/oct-spparms.h liboctave/oct-syscalls.cc liboctave/oct-syscalls.h liboctave/oct-time.cc liboctave/oct-time.h liboctave/oct-uname.cc liboctave/oct-uname.h liboctave/pathlen.h liboctave/pathsearch.cc liboctave/pathsearch.h liboctave/randgamma.c liboctave/randgamma.h liboctave/randmtzig.c liboctave/randmtzig.h liboctave/randpoisson.c liboctave/randpoisson.h liboctave/regexp.cc liboctave/regexp.h liboctave/singleton-cleanup.cc liboctave/singleton-cleanup.h liboctave/sparse-base-chol.cc liboctave/sparse-base-chol.h liboctave/sparse-base-lu.cc liboctave/sparse-base-lu.h liboctave/sparse-dmsolve.cc liboctave/sparse-mk-ops.awk liboctave/sparse-mx-ops liboctave/sparse-sort.cc liboctave/sparse-sort.h liboctave/sparse-util.cc liboctave/sparse-util.h liboctave/statdefs.h liboctave/str-vec.cc liboctave/str-vec.h liboctave/sun-utils.h liboctave/sysdir.h liboctave/syswait.h liboctave/tempnam.c liboctave/tempname.c liboctave/uint16NDArray.cc liboctave/uint16NDArray.h liboctave/uint32NDArray.cc liboctave/uint32NDArray.h liboctave/uint64NDArray.cc liboctave/uint64NDArray.h liboctave/uint8NDArray.cc liboctave/uint8NDArray.h liboctave/util/base-list.h liboctave/vx-ops scripts/help/unimplemented.m src/Makefile.am |
diffstat | 1065 files changed, 9987 insertions(+), 7926 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore +++ b/.hgignore @@ -3,14 +3,18 @@ # to mean "at any directory" while the ^ idiom means "from the # project's top-level directory". -# This one gets created by gnulib during the build, contains no Octave -# files. +# gnulib makes these silly backup files +.~$ + +# This directory gets created by gnulib during the build. +# It contains no Octave files. ^gnulib/ # These directories mostly contain cruft during build time, but they -# do contain some Octave code. -^libgnu/ -^m4/ +# do contain some Octave code, so we gotta be a bit more careful about +# what we ignore here +^libgnu/.*\.([hc]$|sin$|valgrind$|charset$|mk$) +^m4/(?!ax_).+\.m4$ # Emacs tools create these (^|/)TAGS$ @@ -19,7 +23,7 @@ (/|^)Makefile\.in$ ^INSTALL$ -^aclocal\.m4 +^aclocal\.m4$ ^build-.*($|/) ^configure$ ^autom4te\.cache($|/) @@ -33,7 +37,7 @@ ^doc/\w*/version\.texi$ ^doc/interpreter/images\.mk$ -# e.g. liboctave/smx-op-inc.mk -^liboctave/[\w-]*\.mk$ +# e.g. liboctave/operators/smx-op-inc.mk +^liboctave/operators/\w+-op-\w+\.mk$ ^libinterp/dldfcn/module\.mk$
--- a/.hgsubstate +++ b/.hgsubstate @@ -1,2 +1,2 @@ -0e3af50c9e20938bd1cea0182bf749ce61cb6782 gnulib -0f7cc1d7ef5c34b146ff71207ada3ec87a24097c libgui/qterminal +1af55d85d9762a679b4302d5995f05ccd883e956 gnulib +0820083f7fe95d0088971b1233540c7827218e7c libgui/qterminal
--- a/.hgtags +++ b/.hgtags @@ -67,3 +67,5 @@ f947d2922febf12dcd1fb6e21b356756ecb54e55 rc-3-6-2-0 4460c4fb20e6a5d3b1972fa737d4e00eb921545a rc-3-6-2-2 551566201318bf615b27c60ccf9368f4844008bd release-3-6-2 +a95432e7309ca6fc776c02939264bb6d443f3525 release-3-6-3 +2e8eb9ac43a5f8cfaf0423814a312ed47cb80485 rc-3-6-4-0
--- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave +# Makefile for Octave # # Copyright (C) 1993-2012 John W. Eaton # @@ -37,9 +37,9 @@ INSTALL.OCTAVE \ NEWS \ README \ - autogen.sh \ - build-aux/bootstrap \ - build-aux/bootstrap.conf \ + bootstrap \ + build-aux/bootstrap_gnulib \ + build-aux/bootstrap_gnulib.conf \ build-aux/mk-opts.pl \ build-aux/mkinstalldirs \ build-aux/move-if-change \ @@ -67,14 +67,8 @@ include m4/module.mk -if AMCOND_BUILD_GUI -GUIDIR = libgui -else -GUIDIR = -endif - # Subdirectories in which to run `make all'. -SUBDIRS = libgnu libcruft liboctave libinterp $(GUIDIR) src scripts @DOCDIR@ examples test +SUBDIRS = libgnu liboctave libinterp @GUIDIR@ src scripts @DOCDIR@ examples test if ! AMCOND_BUILD_DOCS dist-hook:
--- a/NEWS +++ b/NEWS @@ -3,6 +3,17 @@ ** A new GUI is now available with Octave. + ** Warning states may now be set temporarily, until the end of the + current function, using the syntax + + warning STATE ID "local" + + in which STATE may be "on", "off", or "error". Changes to warning + states that are set locally affect the current function and all + functions called from the current scope. The previous warning state + is restored on return from the current function. The "local" + option is ignored if used in the top-level workspace. + Summary of important user-visible changes for version 3.8: --------------------------------------------------------- @@ -45,9 +56,16 @@ where the pattern is actually the assertion '^' or start-of-line. ** For compatibility with Matlab, the regexp, regexpi, and regexprep - functions now process backslash escapes in single-quoted pattern + functions now process backslash escape sequences in single-quoted pattern strings. In addition, the regexprep function now processes backslash - escapes in single-quoted replacement strings. + escapes in single-quoted replacement strings. For example, + + regexprep (str, '\t', '\n') + + would search the variable str for a TAB character (escape sequence \t) + and replace it with a NEWLINE (escape sequence \n). Previously the + expression would have searched for a literal '\' followed by 't' and + replaced the two characters with the sequence '\', 'n'. ** Redundant terminal comma accepted by parser @@ -82,10 +100,11 @@ ** Other new functions added in 3.8.0: - betaincinv erfcinv polyeig shrinkfaces - cmpermute findfigs splinefit - cmunique fminsearch tetramesh - colorcube lines rgbplot + betaincinv erfcinv lines rgbplot + cmpermute findfigs polyeig shrinkfaces + cmunique fminsearch splinefit + colorcube iscolormap tetramesh + ** Deprecated functions. The following functions were deprecated in Octave 3.4 and have been
--- a/README +++ b/README @@ -66,9 +66,9 @@ bit behind the development of the software. In particular, there is currently no complete documentation of the C++ class libraries. If you notice omissions or inconsistencies, please report them on the -bug tracker at http://savannah.gnu.org/bugs/?group=octave. Specific -suggestions for ways to improve Octave and its documentation are -always welcome. Reports with patches are even more welcome. +bug tracker at http://bugs.octave.org. Specific suggestions for ways +to improve Octave and its documentation are always welcome. Reports +with patches are even more welcome. Additional Information ----------------------
rename from autogen.sh rename to bootstrap --- a/autogen.sh +++ b/bootstrap @@ -1,5 +1,5 @@ #! /bin/sh -# autogen.sh +# bootstrap # Run this to generate all the initial makefiles, etc. set -e @@ -22,9 +22,9 @@ fi done -echo "generating source lists for liboctave/Makefile..." +echo "generating source lists for liboctave/operators/module.mk..." -(cd liboctave; ./config-ops.sh) +(cd liboctave/operators; ./config-ops.sh) echo "generating doc/interpreter/images.mk..." @@ -36,7 +36,7 @@ echo "bootstrapping..." -build-aux/bootstrap "$@" +build-aux/bootstrap_gnulib "$@" ## G77 is obsolete, but it is still the first option in the autoconf Fortran ## macros. We should avoid it, because mixing old versions of g77 with modern
rename from build-aux/bootstrap.conf rename to build-aux/bootstrap_gnulib.conf --- a/build-aux/bootstrap.conf +++ b/build-aux/bootstrap_gnulib.conf @@ -19,17 +19,23 @@ # gnulib modules used by this package. gnulib_modules=" base64 - c-strcase + canonicalize + chdir + close + closedir copysign copysignf - closedir crypto/md5 + dup2 fclose fcntl + fflush filemode + float + floor + floorf fnmatch fopen - fflush fseek ftell getcwd @@ -40,30 +46,35 @@ isatty link lstat + malloc-gnu mkdir mkfifo mkostemp - mkstemp mktime nanosleep nproc + open opendir pathmax + putenv progname readdir readlink + realloc-gnu rename - rewinddir rmdir round roundf + select sigaction signal sigprocmask sleep stat + stddef stdint stdio + strerror strftime strptime symlink
--- a/build-aux/common.mk +++ b/build-aux/common.mk @@ -82,9 +82,9 @@ F77 = @F77@ AM_FFLAGS = @FFLAGS@ FPICFLAG = @FPICFLAG@ -ALL_FFLAGS = $(FFLAGS) F77_FLOAT_STORE_FLAG = @F77_FLOAT_STORE_FLAG@ F77_INTEGER_8_FLAG = @F77_INTEGER_8_FLAG@ +ALL_FFLAGS = $(FFLAGS) F77_TOLOWER=@F77_TOLOWER@ F77_APPEND_UNDERSCORE=@F77_TOLOWER@ @@ -92,35 +92,17 @@ F77_ISNAN_MACRO=@F77_ISNAN_MACRO@ -X11_INCFLAGS = @X11_INCFLAGS@ -X11_LIBS = @X11_LIBS@ - -CARBON_LIBS = @CARBON_LIBS@ - -MAGICK_CPPFLAGS = @MAGICK_CPPFLAGS@ -MAGICK_LDFLAGS = @MAGICK_LDFLAGS@ -MAGICK_LIBS = @MAGICK_LIBS@ - -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ - -LIBFLAGS = -L$(top_builddir) - -DEFS = @DEFS@ - -UGLY_DEFS = @UGLY_DEFS@ +# C compiler flags. CC = @CC@ ## FIXME: CC_VERSION is deprecated and should be removed in version 3.12 CC_VERSION = @CC_VERSION@ GCC_VERSION = @GCC_VERSION@ -CONFIGURE_CFLAGS = @CFLAGS@ CPICFLAG = @CPICFLAG@ XTRA_CFLAGS = @XTRA_CFLAGS@ WARN_CFLAGS = @WARN_CFLAGS@ -AM_CFLAGS = $(CONFIGURE_CFLAGS) \ - $(XTRA_CFLAGS) $(WARN_CFLAGS) -BUG_CFLAGS = $(XTRA_CFLAGS) $(WARN_CFLAGS) $(CFLAGS) +AM_CFLAGS = $(XTRA_CFLAGS) +ALL_CPPFLAGS = $(CPPFLAGS) $(HDF5_CPPFLAGS) $(Z_CPPFLAGS) $(LLVM_CPPFLAGS) BUILD_CC = @BUILD_CC@ BUILD_CFLAGS = @BUILD_CFLAGS@ @@ -132,28 +114,29 @@ # omit_deps = true; # endif -GRAPHICS_CFLAGS = @GRAPHICS_CFLAGS@ +DEFS = @DEFS@ +UGLY_DEFS = @UGLY_DEFS@ + +# C++ compiler flags. CXX = @CXX@ ## FIXME: CXX_VERSION is deprecated and should be removed in version 3.12 CXX_VERSION = @CXX_VERSION@ GXX_VERSION = @GXX_VERSION@ CXXCPP = @CXXCPP@ -CONFIGURE_CXXFLAGS = @CXXFLAGS@ CXXPICFLAG = @CXXPICFLAG@ XTRA_CXXFLAGS = @XTRA_CXXFLAGS@ WARN_CXXFLAGS = @WARN_CXXFLAGS@ -AM_CXXFLAGS = $(CONFIGURE_CXXFLAGS) \ - $(XTRA_CXXFLAGS) $(WARN_CXXFLAGS) -BUG_CXXFLAGS = $(XTRA_CXXFLAGS) $(WARN_CXXFLAGS) $(CXXFLAGS) +AM_CXXFLAGS = $(XTRA_CXXFLAGS) BUILD_CXX = @BUILD_CXX@ BUILD_CXXFLAGS = @BUILD_CXXFLAGS@ -NO_UNDEFINED_LDFLAG = @NO_UNDEFINED_LDFLAG@ +# Linker and library flags LD_CXX = @LD_CXX@ LD_STATIC_FLAG = @LD_STATIC_FLAG@ +LIBFLAGS = -L$(top_builddir) #ALL_LDFLAGS = $(LIBFLAGS) $(LD_STATIC_FLAG) $(CPICFLAG) $(LDFLAGS) BUILD_LDFLAGS = @BUILD_LDFLAGS@ @@ -168,62 +151,33 @@ RDYNAMIC_FLAG = @RDYNAMIC_FLAG@ -FLIBS = @FLIBS@ +NO_UNDEFINED_LDFLAG = @NO_UNDEFINED_LDFLAG@ + +# List of libraries and their special compilation flags LIBOCTINTERP = @LIBOCTINTERP@ LIBOCTAVE = @LIBOCTAVE@ -LIBCRUFT = @LIBCRUFT@ -FT2_CFLAGS = @FT2_CFLAGS@ -FT2_LIBS = @FT2_LIBS@ - -HDF5_CPPFLAGS = @HDF5_CPPFLAGS@ -HDF5_LDFLAGS = @HDF5_LDFLAGS@ -HDF5_LIBS = @HDF5_LIBS@ - -Z_CPPFLAGS = @Z_CPPFLAGS@ -Z_LDFLAGS = @Z_LDFLAGS@ -Z_LIBS = @Z_LIBS@ - -LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ -LLVM_LDFLAGS = @LLVM_LDFLAGS@ -LLVM_LIBS = @LLVM_LIBS@ - -GRAPHICS_LIBS = @GRAPHICS_LIBS@ - -QHULL_CPPFLAGS = @QHULL_CPPFLAGS@ -QHULL_LDFLAGS = @QHULL_LDFLAGS@ -QHULL_LIBS = @QHULL_LIBS@ - -REGEX_LIBS = @REGEX_LIBS@ - -LAPACK_LIBS = @LAPACK_LIBS@ -BLAS_LIBS = @BLAS_LIBS@ - -FFTW3_CPPFLAGS = @FFTW3_CPPFLAGS@ -FFTW3_LDFLAGS = @FFTW3_LDFLAGS@ -FFTW3_LIBS = @FFTW3_LIBS@ - -FFTW3F_CPPFLAGS = @FFTW3F_CPPFLAGS@ -FFTW3F_LDFLAGS = @FFTW3F_LDFLAGS@ -FFTW3F_LIBS = @FFTW3F_LIBS@ - -GLPK_CPPFLAGS = @GLPK_CPPFLAGS@ -GLPK_LDFLAGS = @GLPK_LDFLAGS@ -GLPK_LIBS = @GLPK_LIBS@ - -CURL_CPPFLAGS = @CURL_CPPFLAGS@ -CURL_LDFLAGS = @CURL_LDFLAGS@ -CURL_LIBS = @CURL_LIBS@ +DL_LIBS = @DL_LIBS@ +FLIBS = @FLIBS@ +LIBS = @LIBS@ AMD_CPPFLAGS = @AMD_CPPFLAGS@ AMD_LDFLAGS = @AMD_LDFLAGS@ AMD_LIBS = @AMD_LIBS@ +ARPACK_CPPFLAGS = @ARPACK_CPPFLAGS@ +ARPACK_LDFLAGS = @ARPACK_LDFLAGS@ +ARPACK_LIBS = @ARPACK_LIBS@ + +BLAS_LIBS = @BLAS_LIBS@ + CAMD_CPPFLAGS = @CAMD_CPPFLAGS@ CAMD_LDFLAGS = @CAMD_LDFLAGS@ CAMD_LIBS = @CAMD_LIBS@ +CARBON_LIBS = @CARBON_LIBS@ + COLAMD_CPPFLAGS = @COLAMD_CPPFLAGS@ COLAMD_LDFLAGS = @COLAMD_LDFLAGS@ COLAMD_LIBS = @COLAMD_LIBS@ @@ -236,31 +190,66 @@ CHOLMOD_LDFLAGS = @CHOLMOD_LDFLAGS@ CHOLMOD_LIBS = @CHOLMOD_LIBS@ +CURL_CPPFLAGS = @CURL_CPPFLAGS@ +CURL_LDFLAGS = @CURL_LDFLAGS@ +CURL_LIBS = @CURL_LIBS@ + CXSPARSE_CPPFLAGS = @CXSPARSE_CPPFLAGS@ CXSPARSE_LDFLAGS = @CXSPARSE_LDFLAGS@ CXSPARSE_LIBS = @CXSPARSE_LIBS@ -UMFPACK_CPPFLAGS = @UMFPACK_CPPFLAGS@ -UMFPACK_LDFLAGS = @UMFPACK_LDFLAGS@ -UMFPACK_LIBS = @UMFPACK_LIBS@ +FFTW3_CPPFLAGS = @FFTW3_CPPFLAGS@ +FFTW3_LDFLAGS = @FFTW3_LDFLAGS@ +FFTW3_LIBS = @FFTW3_LIBS@ + +FFTW3F_CPPFLAGS = @FFTW3F_CPPFLAGS@ +FFTW3F_LDFLAGS = @FFTW3F_LDFLAGS@ +FFTW3F_LIBS = @FFTW3F_LIBS@ + +FFTW_XCPPFLAGS = $(FFTW3_CPPFLAGS) $(FFTW3F_CPPFLAGS) +FFTW_XLDFLAGS = $(FFTW3_LDFLAGS) $(FFTW3F_LDFLAGS) +FFTW_XLIBS = $(FFTW3_LIBS) $(FFTW3F_LIBS) + +FT2_CFLAGS = @FT2_CFLAGS@ +FT2_LIBS = @FT2_LIBS@ + +GLPK_CPPFLAGS = @GLPK_CPPFLAGS@ +GLPK_LDFLAGS = @GLPK_LDFLAGS@ +GLPK_LIBS = @GLPK_LIBS@ + +GRAPHICS_CFLAGS = @GRAPHICS_CFLAGS@ +GRAPHICS_LIBS = @GRAPHICS_LIBS@ + +HDF5_CPPFLAGS = @HDF5_CPPFLAGS@ +HDF5_LDFLAGS = @HDF5_LDFLAGS@ +HDF5_LIBS = @HDF5_LIBS@ + +LAPACK_LIBS = @LAPACK_LIBS@ + +LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBS = @LLVM_LIBS@ + +MAGICK_CPPFLAGS = @MAGICK_CPPFLAGS@ +MAGICK_LDFLAGS = @MAGICK_LDFLAGS@ +MAGICK_LIBS = @MAGICK_LIBS@ OPENGL_LIBS = @OPENGL_LIBS@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ + +QHULL_CPPFLAGS = @QHULL_CPPFLAGS@ +QHULL_LDFLAGS = @QHULL_LDFLAGS@ +QHULL_LIBS = @QHULL_LIBS@ + QRUPDATE_CPPFLAGS = @QRUPDATE_CPPFLAGS@ QRUPDATE_LDFLAGS = @QRUPDATE_LDFLAGS@ QRUPDATE_LIBS = @QRUPDATE_LIBS@ -READLINE_LIBS = @READLINE_LIBS@ -TERM_LIBS = @TERM_LIBS@ +REGEX_LIBS = @REGEX_LIBS@ -ARPACK_CPPFLAGS = @ARPACK_CPPFLAGS@ -ARPACK_LDFLAGS = @ARPACK_LDFLAGS@ -ARPACK_LIBS = @ARPACK_LIBS@ - -DL_LIBS = @DL_LIBS@ -LIBS = @LIBS@ - -ALL_CPPFLAGS = $(CPPFLAGS) $(HDF5_CPPFLAGS) $(Z_CPPFLAGS) $(LLVM_CPPFLAGS) +READLINE_LIBS = @READLINE_LIBS@ SPARSE_XCPPFLAGS = \ $(CHOLMOD_CPPFLAGS) $(UMFPACK_CPPFLAGS) \ @@ -278,11 +267,20 @@ $(AMD_LIBS) $(CAMD_LIBS) $(COLAMD_LIBS) \ $(CCOLAMD_LIBS) $(CXSPARSE_LIBS) -FFTW_XCPPFLAGS = $(FFTW3_CPPFLAGS) $(FFTW3F_CPPFLAGS) +TERM_LIBS = @TERM_LIBS@ + +UMFPACK_CPPFLAGS = @UMFPACK_CPPFLAGS@ +UMFPACK_LDFLAGS = @UMFPACK_LDFLAGS@ +UMFPACK_LIBS = @UMFPACK_LIBS@ -FFTW_XLDFLAGS = $(FFTW3_LDFLAGS) $(FFTW3F_LDFLAGS) +X11_INCFLAGS = @X11_INCFLAGS@ +X11_LIBS = @X11_LIBS@ -FFTW_XLIBS = $(FFTW3_LIBS) $(FFTW3F_LIBS) +Z_CPPFLAGS = @Z_CPPFLAGS@ +Z_LDFLAGS = @Z_LDFLAGS@ +Z_LIBS = @Z_LIBS@ + +# Miscellaneous USE_64_BIT_IDX_T = @USE_64_BIT_IDX_T@ OCTAVE_IDX_TYPE = @OCTAVE_IDX_TYPE@ @@ -329,7 +327,7 @@ # Where to install and expect extra files like NEWS and doc-cache. octetcdir = @octetcdir@ -# Where to install and expect libraries like libcruft.a, liboctave.a, +# Where to install and expect libraries like liboctave.a, liboctinterp.a, # and other architecture-dependent data. octlibdir = @octlibdir@ @@ -431,6 +429,8 @@ NO_OCT_FILE_STRIP = @NO_OCT_FILE_STRIP@ +# ==================== Octave-specific Makefile rules ==================== + # The following pattern rules and the substitution functions require # GNU make. If you don't have it, get it! @@ -510,9 +510,10 @@ -e "s|%OCTAVE_CONF_DL_LD%|\"${DL_LD}\"|" \ -e "s|%OCTAVE_CONF_DL_LDFLAGS%|\"${DL_LDFLAGS}\"|" \ -e "s|%OCTAVE_CONF_DL_LIBS%|\"${DL_LIBS}\"|" \ + -e "s|%OCTAVE_CONF_ENABLE_DYNAMIC_LINKING%|\"${ENABLE_DYNAMIC_LINKING}\"|" \ + -e "s|%OCTAVE_CONF_EXEEXT%|\"${EXEEXT}\"|" \ -e "s|%OCTAVE_CONF_GCC_VERSION%|\"${GCC_VERSION}\"|" \ -e "s|%OCTAVE_CONF_GXX_VERSION%|\"${GXX_VERSION}\"|" \ - -e "s|%OCTAVE_CONF_EXEEXT%|\"${EXEEXT}\"|" \ -e "s|%OCTAVE_CONF_F77%|\"${F77}\"|" \ -e "s|%OCTAVE_CONF_F77_FLOAT_STORE_FLAG%|\"${F77_FLOAT_STORE_FLAG}\"|" \ -e "s|%OCTAVE_CONF_F77_INTEGER_8_FLAG%|\"${F77_INTEGER_8_FLAG}\"|" \ @@ -526,11 +527,13 @@ -e "s|%OCTAVE_CONF_FFTW3F_LIBS%|\"${FFTW3F_LIBS}\"|" \ -e "s|%OCTAVE_CONF_FLIBS%|\"${FLIBS}\"|" \ -e "s|%OCTAVE_CONF_FPICFLAG%|\"${FPICFLAG}\"|" \ + -e "s|%OCTAVE_CONF_FT2_CFLAGS%|\"${FT2_CFLAGS}\"|" \ -e "s|%OCTAVE_CONF_FT2_LIBS%|\"${FT2_LIBS}\"|" \ -e "s|%OCTAVE_CONF_GLPK_CPPFLAGS%|\"${GLPK_CPPFLAGS}\"|" \ -e "s|%OCTAVE_CONF_GLPK_LDFLAGS%|\"${GLPK_LDFLAGS}\"|" \ -e "s|%OCTAVE_CONF_GLPK_LIBS%|\"${GLPK_LIBS}\"|" \ -e "s|%OCTAVE_CONF_GNUPLOT%|\"${GNUPLOT}\"|" \ + -e "s|%OCTAVE_CONF_GRAPHICS_CFLAGS%|\"${GRAPHICS_CFLAGS}\"|" \ -e "s|%OCTAVE_CONF_GRAPHICS_LIBS%|\"${GRAPHICS_LIBS}\"|" \ -e "s|%OCTAVE_CONF_HDF5_CPPFLAGS%|\"${HDF5_CPPFLAGS}\"|" \ -e "s|%OCTAVE_CONF_HDF5_LDFLAGS%|\"${HDF5_LDFLAGS}\"|" \ @@ -543,20 +546,19 @@ -e "s|%OCTAVE_CONF_LEX%|\"${LEX}\"|" \ -e "s|%OCTAVE_CONF_LEXLIB%|\"${LEXLIB}\"|" \ -e "s|%OCTAVE_CONF_LFLAGS%|\"${LFLAGS}\"|" \ - -e "s|%OCTAVE_CONF_LIBCRUFT%|\"${LIBCRUFT}\"|" \ -e "s|%OCTAVE_CONF_LIBDIR%|\"${libdir}\"|" \ -e "s|%OCTAVE_CONF_LIBEXT%|\"${LIBEXT}\"|" \ -e "s|%OCTAVE_CONF_LIBFLAGS%|\"${LIBFLAGS}\"|" \ -e "s|%OCTAVE_CONF_LIBOCTAVE%|\"${LIBOCTAVE}\"|" \ -e "s|%OCTAVE_CONF_LIBOCTINTERP%|\"${LIBOCTINTERP}\"|" \ -e "s|%OCTAVE_CONF_LIBS%|\"${LIBS}\"|" \ + -e "s|%OCTAVE_CONF_LLVM_CPPFLAGS%|\"${LLVM_CPPFLAGS}\"|" \ + -e "s|%OCTAVE_CONF_LLVM_LDFLAGS%|\"${LLVM_LDFLAGS}\"|" \ + -e "s|%OCTAVE_CONF_LLVM_LIBS%|\"${LLVM_LIBS}\"|" \ -e "s|%OCTAVE_CONF_LN_S%|\"${LN_S}\"|" \ -e "s|%OCTAVE_CONF_MAGICK_CPPFLAGS%|\"${MAGICK_CPPFLAGS}\"|" \ -e "s|%OCTAVE_CONF_MAGICK_LDFLAGS%|\"${MAGICK_LDFLAGS}\"|" \ -e "s|%OCTAVE_CONF_MAGICK_LIBS%|\"${MAGICK_LIBS}\"|" \ - -e "s|%OCTAVE_CONF_LLVM_CPPFLAGS%|\"${LLVM_CPPFLAGS}\"|" \ - -e "s|%OCTAVE_CONF_LLVM_LDFLAGS%|\"${LLVM_LDFLAGS}\"|" \ - -e "s|%OCTAVE_CONF_LLVM_LIBS%|\"${LLVM_LIBS}\"|" \ -e 's|%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%|\"@MKOCTFILE_DL_LDFLAGS@\"|' \ -e "s|%OCTAVE_CONF_OCTAVE_LINK_DEPS%|\"${OCTAVE_LINK_DEPS}\"|" \ -e "s|%OCTAVE_CONF_OCTAVE_LINK_OPTS%|\"${OCTAVE_LINK_OPTS}\"|" \ @@ -596,7 +598,8 @@ -e "s|%OCTAVE_CONF_UMFPACK_LIBS%|\"${UMFPACK_LIBS}\"|" \ -e "s|%OCTAVE_CONF_USE_64_BIT_IDX_T%|\"${USE_64_BIT_IDX_T}\"|" \ -e "s|%OCTAVE_CONF_VERSION%|\"${version}\"|" \ - -e "s|%OCTAVE_CONF_ENABLE_DYNAMIC_LINKING%|\"${ENABLE_DYNAMIC_LINKING}\"|" \ + -e "s|%OCTAVE_CONF_WARN_CFLAGS%|\"${WARN_CFLAGS}\"|" \ + -e "s|%OCTAVE_CONF_WARN_CXXFLAGS%|\"${WARN_CXXFLAGS}\"|" \ -e "s|%OCTAVE_CONF_X11_INCFLAGS%|\"${X11_INCFLAGS}\"|" \ -e "s|%OCTAVE_CONF_X11_LIBS%|\"${X11_LIBS}\"|" \ -e "s|%OCTAVE_CONF_XTRA_CFLAGS%|\"${XTRA_CFLAGS}\"|" \ @@ -665,7 +668,6 @@ -e "s|%library_path_var%|${library_path_var}|g" \ -e "s|%liboctinterp%|${SHLPRE}octinterp.${SHLEXT}|g" \ -e "s|%liboctave%|${SHLPRE}octave.${SHLEXT}|g" \ - -e "s|%libcruft%|${SHLPRE}cruft.${SHLEXT}|g" \ -e "s|%ldpreloadsep%|${ldpreloadsep}|g" \ -e "s|%srcdir%|${srcdir}|" \ -e "s|%top_srcdir%|${top_srcdir}|" \
--- a/configure.ac +++ b/configure.ac @@ -58,17 +58,16 @@ ### Path separator. -sepchar=: -AC_ARG_WITH(sepchar, +sepchar=':' +AC_ARG_WITH([sepchar], [AS_HELP_STRING([--with-sepchar=<char>], [use <char> as the path separation character])]) case $with_sepchar in yes | "") - case "$canonical_host_type" in + case $canonical_host_type in *-*-mingw* | *-*-msdosmsvc) - sepchar=';' - ;; - esac + sepchar=';' ;; + esac ;; no) AC_MSG_ERROR([You are required to define a path separation character]) @@ -85,36 +84,36 @@ ### Set default file locations -OCTAVE_SET_DEFAULT(man1dir, '$(mandir)/man1') -OCTAVE_SET_DEFAULT(man1ext, '.1') -OCTAVE_SET_DEFAULT(doc_cache_file, '$(octetcdir)/doc-cache') -OCTAVE_SET_DEFAULT(texi_macros_file, '$(octetcdir)/macros.texi') -OCTAVE_SET_DEFAULT(infofile, '$(infodir)/octave.info') -OCTAVE_SET_DEFAULT(octincludedir, '$(includedir)/octave-$(version)/octave') -OCTAVE_SET_DEFAULT(fcnfiledir, '$(datadir)/octave/$(version)/m') -OCTAVE_SET_DEFAULT(localfcnfiledir, '$(datadir)/octave/site/m') -OCTAVE_SET_DEFAULT(localapifcnfiledir, +OCTAVE_SET_DEFAULT([man1dir], '$(mandir)/man1') +OCTAVE_SET_DEFAULT([man1ext], '.1') +OCTAVE_SET_DEFAULT([doc_cache_file], '$(octetcdir)/doc-cache') +OCTAVE_SET_DEFAULT([texi_macros_file], '$(octetcdir)/macros.texi') +OCTAVE_SET_DEFAULT([infofile], '$(infodir)/octave.info') +OCTAVE_SET_DEFAULT([octincludedir], '$(includedir)/octave-$(version)/octave') +OCTAVE_SET_DEFAULT([fcnfiledir], '$(datadir)/octave/$(version)/m') +OCTAVE_SET_DEFAULT([localfcnfiledir], '$(datadir)/octave/site/m') +OCTAVE_SET_DEFAULT([localapifcnfiledir], '$(datadir)/octave/site/$(api_version)/m') -OCTAVE_SET_DEFAULT(localverfcnfiledir, '$(datadir)/octave/$(version)/site/m') -OCTAVE_SET_DEFAULT(octetcdir, '$(datadir)/octave/$(version)/etc') -OCTAVE_SET_DEFAULT(octlibdir, '$(libdir)/octave/$(version)') -OCTAVE_SET_DEFAULT(archlibdir, +OCTAVE_SET_DEFAULT([localverfcnfiledir], '$(datadir)/octave/$(version)/site/m') +OCTAVE_SET_DEFAULT([octetcdir], '$(datadir)/octave/$(version)/etc') +OCTAVE_SET_DEFAULT([octlibdir], '$(libdir)/octave/$(version)') +OCTAVE_SET_DEFAULT([archlibdir], '$(libexecdir)/octave/$(version)/exec/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localarchlibdir, +OCTAVE_SET_DEFAULT([localarchlibdir], '$(libexecdir)/octave/site/exec/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localapiarchlibdir, +OCTAVE_SET_DEFAULT([localapiarchlibdir], '$(libexecdir)/octave/$(api_version)/site/exec/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localverarchlibdir, +OCTAVE_SET_DEFAULT([localverarchlibdir], '$(libexecdir)/octave/$(version)/site/exec/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(octfiledir, +OCTAVE_SET_DEFAULT([octfiledir], '$(libdir)/octave/$(version)/oct/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localoctfiledir, +OCTAVE_SET_DEFAULT([localoctfiledir], '$(libdir)/octave/site/oct/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localapioctfiledir, +OCTAVE_SET_DEFAULT([localapioctfiledir], '$(libdir)/octave/site/oct/$(api_version)/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(localveroctfiledir, +OCTAVE_SET_DEFAULT([localveroctfiledir], '$(libdir)/octave/$(version)/site/oct/$(canonical_host_type)') -OCTAVE_SET_DEFAULT(imagedir, '$(datadir)/octave/$(version)/imagelib') +OCTAVE_SET_DEFAULT([imagedir], '$(datadir)/octave/$(version)/imagelib') ### Find pkg-config executable (sets $PKG_CONFIG) @@ -130,9 +129,9 @@ ### by default. BOUNDS_CHECKING=false -AC_ARG_ENABLE(bounds-check, +AC_ARG_ENABLE([bounds-check], [AS_HELP_STRING([--enable-bounds-check], - [bounds checking for indexing in internal array classes (default is no)])], + [enable bounds checking for indexing in internal array classes])], [if test "$enableval" = yes; then BOUNDS_CHECKING=true; fi], []) if $BOUNDS_CHECKING; then AC_DEFINE(BOUNDS_CHECKING, 1, [Define to 1 to use internal bounds checking.]) @@ -142,9 +141,9 @@ ### Disabled by default. USE_OCTAVE_ALLOCATOR=false -AC_ARG_ENABLE(octave-allocator, +AC_ARG_ENABLE([octave-allocator], [AS_HELP_STRING([--enable-octave-allocator], - [use the obsolete octave_allocator class for many of Octave's objects (mostly octave_value types). You probably do NOT want to enable this feature. (default is no)])], + [use the obsolete octave_allocator class for many of Octave's objects (mostly octave_value types). You probably do NOT want to enable this feature.])], [if test "$enableval" = yes; then USE_OCTAVE_ALLOCATOR=true; fi], []) if $USE_OCTAVE_ALLOCATOR; then AC_DEFINE(USE_OCTAVE_ALLOCATOR, 1, @@ -156,9 +155,9 @@ ### disabled by default. USE_ATOMIC_REFCOUNT=false -AC_ARG_ENABLE(atomic-refcount, +AC_ARG_ENABLE([atomic-refcount], [AS_HELP_STRING([--enable-atomic-refcount], - [use atomic operations for internal reference counting. This is required for thread-safe behavior. (default is no)])], + [use atomic operations for internal reference counting. This is required for thread-safe behavior but does not by itself make Octave internals thread safe.])], [if test "$enableval" = yes; then USE_ATOMIC_REFCOUNT=true; fi], []) if $USE_ATOMIC_REFCOUNT; then AC_DEFINE(USE_ATOMIC_REFCOUNT, 1, @@ -169,8 +168,8 @@ ### This is useful, for example, when building Octave on systems without TeX. DOCDIR=doc -AC_ARG_ENABLE(docs, - [AS_HELP_STRING([--enable-docs], [build documentation (default is yes)])], +AC_ARG_ENABLE([docs], + [AS_HELP_STRING([--disable-docs], [don't build documentation files])], [if test "$enableval" = no; then DOCDIR= warn_docs="building documentation disabled; make dist will fail" @@ -188,9 +187,9 @@ [(EXPERIMENTAL) use 64-bit integers for array dimensions and indexing])], [if test "$enableval" = yes; then USE_64_BIT_IDX_T=true; fi], []) if $USE_64_BIT_IDX_T; then - AC_CHECK_SIZEOF(void *) - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF([void *]) + AC_CHECK_SIZEOF([int]) + AC_CHECK_SIZEOF([long]) if test $ac_cv_sizeof_void_p -eq 8; then if test $ac_cv_sizeof_int -eq 8; then OCTAVE_IDX_TYPE=int @@ -209,7 +208,7 @@ fi fi AC_SUBST(OCTAVE_IDX_TYPE) -AC_DEFINE_UNQUOTED(OCTAVE_IDX_TYPE, $OCTAVE_IDX_TYPE, +AC_DEFINE_UNQUOTED(OCTAVE_IDX_TYPE, [$OCTAVE_IDX_TYPE], [Define to the type of octave_idx_type (64 or 32 bit signed integer).]) if $USE_64_BIT_IDX_T; then AC_DEFINE(USE_64_BIT_IDX_T, 1, @@ -240,12 +239,12 @@ AX_COMPARE_VERSION([$gxx_version], [lt], [3.5], [AC_MSG_ERROR([g++ version $gxx_version will probably fail to compile Octave])]) - GXX_VERSION="$gxx_version" + GXX_VERSION=$gxx_version fi AC_SUBST(GXX_VERSION) -## FIXME: CXX_VERSION is deprecated and should be removed in version 3.12 -CXX_VERSION="$gxx_version" +## FIXME: CXX_VERSION is deprecated and should be removed in Octave version 3.12 +CXX_VERSION=$gxx_version AC_SUBST(CXX_VERSION) ### Determine which C compiler to use (we expect to find gcc). @@ -256,7 +255,7 @@ ## Check for MSVC have_msvc=no -case "$canonical_host_type" in +case $canonical_host_type in *-*-msdosmsvc) have_msvc=yes ;; @@ -288,12 +287,12 @@ [warn_gcc_version="gcc version $gcc_version is likely to cause problems" OCTAVE_CONFIGURE_WARNING([warn_gcc_version])]) - GCC_VERSION="$gcc_version" + GCC_VERSION=$gcc_version fi AC_SUBST(CC_VERSION) -## FIXME: CC_VERSION is deprecated and should be removed in version 3.12 -CC_VERSION="$gcc_version" +## FIXME: CC_VERSION is deprecated and should be removed in Octave version 3.12 +CC_VERSION=$gcc_version AC_SUBST(GCC_VERSION) ### Determine the compiler flag necessary to create dependencies @@ -302,10 +301,8 @@ INCLUDE_DEPS=true DEPEND_FLAGS="-M" DEPEND_EXTRA_SED_PATTERN="" -if test "$GCC" = yes; then - true -else - case "$canonical_host_type" in +if test "$GCC" != yes; then + case $canonical_host_type in sparc-sun-solaris2* | i386-pc-solaris2*) DEPEND_FLAGS="-xM1" DEPEND_EXTRA_SED_PATTERN="-e '/\/opt\/SUNWspro/d'" @@ -313,7 +310,7 @@ *-*-msdosmsvc) ;; *-*-mingw*) - if test "$have_msvc" = "no"; then + if test $have_msvc = no; then INCLUDE_DEPS=false fi ;; @@ -342,17 +339,17 @@ ### Thus, we provide a FLOAT_TRUNCATE macro that may be defined to "volatile" ### when compiling for x87 target, or left empty for modern SSE math, that ### doesn't suffer from this problem at all. -AC_ARG_ENABLE(float-truncate, +AC_ARG_ENABLE([float-truncate], [AS_HELP_STRING([--enable-float-truncate], [enables truncating intermediate FP results.])], [if test "$enableval" = yes; then - ac_float_truncate=volatile; + ac_float_truncate=volatile else - ac_float_truncate=; + ac_float_truncate= fi], [ac_float_truncate=]) -AC_DEFINE_UNQUOTED(FLOAT_TRUNCATE, $ac_float_truncate, +AC_DEFINE_UNQUOTED(FLOAT_TRUNCATE, [$ac_float_truncate], [Define to volatile if you need to truncate intermediate FP results.]) ### Determine extra CFLAGS that may be necessary for Octave. @@ -363,16 +360,16 @@ ## On Alpha/OSF systems, we need -mieee. ieee_fp_flag= -case "$canonical_host_type" in +case $canonical_host_type in i[[3456789]]86-*-*) if test "$GCC" = yes; then - OCTAVE_CC_FLAG(-mieee-fp, [ + OCTAVE_CC_FLAG([-mieee-fp], [ ieee_fp_flag=-mieee-fp XTRA_CFLAGS="$XTRA_CFLAGS -mieee-fp" AC_MSG_NOTICE([adding -mieee-fp to XTRA_CFLAGS])]) fi if test "$GXX" = yes; then - OCTAVE_CXX_FLAG(-mieee-fp, [ + OCTAVE_CXX_FLAG([-mieee-fp], [ ieee_fp_flag=-mieee-fp XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee-fp" AC_MSG_NOTICE([adding -mieee-fp to XTRA_CXXFLAGS])]) @@ -380,33 +377,33 @@ ;; alpha*-*-*) if test "$GCC" = yes; then - OCTAVE_CC_FLAG(-mieee, [ + OCTAVE_CC_FLAG([-mieee], [ ieee_fp_flag=-mieee XTRA_CFLAGS="$XTRA_CFLAGS -mieee" AC_MSG_NOTICE([adding -mieee to XTRA_CFLAGS])]) else - OCTAVE_CC_FLAG(-ieee, [ + OCTAVE_CC_FLAG([-ieee], [ ieee_fp_flag=-ieee XTRA_CFLAGS="$XTRA_CFLAGS -ieee" AC_MSG_NOTICE([adding -ieee to XTRA_CFLAGS])]) fi if test "$GXX" = yes; then - OCTAVE_CXX_FLAG(-mieee, [ + OCTAVE_CXX_FLAG([-mieee], [ ieee_fp_flag=-mieee XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mieee" AC_MSG_NOTICE([adding -mieee to XTRA_CXXFLAGS])]) else - OCTAVE_CXX_FLAG(-ieee, [ + OCTAVE_CXX_FLAG([-ieee], [ ieee_fp_flag=-ieee XTRA_CXXFLAGS="$XTRA_CXXFLAGS -ieee" AC_MSG_NOTICE([adding -ieee to XTRA_CXXFLAGS])]) fi ;; *ibm-aix4*) - OCTAVE_CC_FLAG(-mminimal-toc, [ + OCTAVE_CC_FLAG([-mminimal-toc], [ XTRA_CFLAGS="$XTRA_CFLAGS -mminimal-toc"]) - OCTAVE_CXX_FLAG(-mminimal-toc, [ + OCTAVE_CXX_FLAG([-mminimal-toc], [ XTRA_CXXFLAGS="$XTRA_CXXFLAGS -mminimal-toc"]) ;; esac @@ -418,12 +415,12 @@ ### it by default. Enable it with the flag --enable-openmp. USE_OPENMP=false -AC_ARG_ENABLE(openmp, +AC_ARG_ENABLE([openmp], [AS_HELP_STRING([--enable-openmp], [(EXPERIMENTAL) use OpenMP SMP multi-threading])], [if test "$enableval" = yes; then USE_OPENMP=true; fi], []) if $USE_OPENMP; then - case "$canonical_host_type" in + case $canonical_host_type in *-*-mingw* | *-*-cygwin* | *-*-gnu*) OCTAVE_CHECK_OPENMP(-fopenmp) ;; @@ -453,32 +450,20 @@ BUILD_CXX='$(CXX)' BUILD_CXXFLAGS='$(CXXFLAGS)' BUILD_LDFLAGS='$(LDFLAGS)' - ## 2012/07/31: Commented out special build requirements - ## for Sun compiler now that gendoc.cc is no longer part of build. - ################################################################## - #case "$canonical_host_type" in - # sparc-sun-solaris2*) - # if test "$GCC" != yes; then - # ## The Sun C++ compiler never seems to complete compiling - # ## gendoc.cc unless we reduce the optimization level... - # ## BUILD_CXXFLAGS="-g -O1" - # fi - # ;; - #esac BUILD_EXEEXT='$(EXEEXT)' fi -AC_ARG_VAR(BUILD_CC, +AC_ARG_VAR([BUILD_CC], [build system C compiler (used if cross compiling)]) -AC_ARG_VAR(BUILD_CFLAGS, +AC_ARG_VAR([BUILD_CFLAGS], [build system C compiler flags (used if cross compiling)]) -AC_ARG_VAR(BUILD_CXX, +AC_ARG_VAR([BUILD_CXX], [build system C++ compiler (used if cross compiling)]) -AC_ARG_VAR(BUILD_CXXFLAGS, +AC_ARG_VAR([BUILD_CXXFLAGS], [build system C++ compiler flags (used if cross compiling)]) -AC_ARG_VAR(BUILD_LDFLAGS, +AC_ARG_VAR([BUILD_LDFLAGS], [build system C++ compiler link flags (used if cross compiling)]) -AC_ARG_VAR(BUILD_EXEEXT, +AC_ARG_VAR([BUILD_EXEEXT], [build system executable extension (used if cross compiling)]) dnl This is bogus. We shouldn't have to explicitly add libc too! @@ -487,7 +472,7 @@ ### Look for math library. If found, this will add -lm to LIBS. -case "$canonical_host_type" in +case $canonical_host_type in *-*-linux*) AC_CHECK_LIB(m, sin, , , -lc) ;; @@ -499,7 +484,7 @@ ### Determine the Fortran compiler and how to invoke it ## Default FFLAGS is -O. -if test "x$FFLAGS" = x; then +if test x"$FFLAGS" = x""; then FFLAGS="-O" fi @@ -513,28 +498,28 @@ F77_APPEND_UNDERSCORE=true F77_APPEND_EXTRA_UNDERSCORE=true -case "$ac_cv_f77_mangling" in +case $ac_cv_f77_mangling in "upper case") F77_TOLOWER=false ;; esac -case "$ac_cv_f77_mangling" in +case $ac_cv_f77_mangling in "no underscore") F77_APPEND_UNDERSCORE=false ;; esac -case "$ac_cv_f77_mangling" in +case $ac_cv_f77_mangling in "no extra underscore") F77_APPEND_EXTRA_UNDERSCORE=false ;; esac -case "$canonical_host_type" in +case $canonical_host_type in i[[3456789]]86-*-*) - if test "$ac_cv_f77_compiler_gnu" = yes; then - OCTAVE_F77_FLAG(-mieee-fp) + if test $ac_cv_f77_compiler_gnu = yes; then + OCTAVE_F77_FLAG([-mieee-fp]) fi ;; alpha*-*-*) - if test "$ac_cv_f77_compiler_gnu" = yes; then - OCTAVE_F77_FLAG(-mieee) + if test $ac_cv_f77_compiler_gnu = yes; then + OCTAVE_F77_FLAG([-mieee]) else - OCTAVE_F77_FLAG(-ieee) - OCTAVE_F77_FLAG(-fpe1) + OCTAVE_F77_FLAG([-ieee]) + OCTAVE_F77_FLAG([-fpe1]) fi ;; powerpc-apple-machten*) @@ -556,22 +541,22 @@ OCTAVE_CHECK_FUNC_FORTRAN_ISNAN F77_ISNAN_MACRO= -if test "x$octave_cv_func_fortran_isnan" = xno; then +if test $octave_cv_func_fortran_isnan = no; then AC_MSG_NOTICE([substituting ISNAN(X) with X.NE.X in Fortran sources]) F77_ISNAN_MACRO="s|ISNAN(\(@<:@^)@:>@*\))|(\1.NE.\1)|" fi AC_SUBST(F77_ISNAN_MACRO) OCTAVE_CHECK_SIZEOF_FORTRAN_INTEGER -if test "x$octave_cv_sizeof_fortran_integer" = xno; then +if test $octave_cv_sizeof_fortran_integer = no; then if $USE_64_BIT_IDX_T; then - case "$F77" in + case $F77 in *gfortran*) - case "$F77_INTEGER_8_FLAG" in + case $F77_INTEGER_8_FLAG in *-fdefault-integer-8*) ;; *) - case "$FFLAGS" in + case $FFLAGS in *-fdefault-integer-8*) AC_MSG_NOTICE([setting -fdefault-integer-8 in F77_INTEGER_8_FLAG instead of FFLAGS]) FFLAGS=`echo $FFLAGS | sed 's/-fdefault-integer-8//g'` @@ -591,7 +576,7 @@ if test -z "$octave_cv_sizeof_fortran_integer"; then OCTAVE_CHECK_SIZEOF_FORTRAN_INTEGER fi - if test "x$octave_cv_sizeof_fortran_integer" = xno; then + if test $octave_cv_sizeof_fortran_integer = no; then AC_MSG_ERROR([in order to build Octave with 64-bit indexing support your Fortran compiler must have an option for setting the default integer size to 8 bytes. See the file INSTALL for more information.]) fi else @@ -600,10 +585,11 @@ fi AC_SUBST(F77_INTEGER_8_FLAG) +## FIXME: Is this really used? Makefile seems to use $F77 for compiler FC=$F77 AC_SUBST(FC) -OCTAVE_F77_FLAG(-ffloat-store, [ +OCTAVE_F77_FLAG([-ffloat-store], [ AC_MSG_RESULT([setting F77_FLOAT_STORE_FLAG to -ffloat-store]) F77_FLOAT_STORE_FLAG=-ffloat-store AC_SUBST(F77_FLOAT_STORE_FLAG) @@ -636,7 +622,7 @@ #if defined (HAVE_PCRE_H) # include <pcre.h> #elif defined (HAVE_PCRE_PCRE_H) - # include <pcre.h> + # include <pcre/pcre.h> #error "NO PCRE HEADER" #endif #if defined (PCRE_INFO_NAMECOUNT) \ @@ -651,13 +637,13 @@ AC_CHECK_PROG(HAVE_PCRE_CONFIG, pcre-config, [yes], [no]) if test $HAVE_PCRE_CONFIG = yes; then XTRA_CXXFLAGS="$XTRA_CXXFLAGS `pcre-config --cflags`" - REGEX_LIBS="`pcre-config --libs`" + REGEX_LIBS=`pcre-config --libs` else REGEX_LIBS="-lpcre" fi save_LIBS="$LIBS" LIBS="$REGEX_LIBS $LIBS" - AC_CHECK_FUNCS(pcre_compile, + AC_CHECK_FUNCS([pcre_compile], [AC_SUBST(REGEX_LIBS)], [AC_MSG_ERROR([$pcre_fail_msg])]) LIBS="$save_LIBS" @@ -672,100 +658,91 @@ [zlib.h], [gzclearerr]) ### Check for the LLVM library -dnl -dnl LLVM is odd and has its own pkg-config like script. We should probably -dnl check for existence and ???. -dnl -save_CPPFLAGS="$CPPFLAGS" -save_CXXFLAGS="$CXXFLAGS" -save_LIBS="$LIBS" -save_LDFLAGS="$LDFLAGS" -warn_llvm="LLVM library fails tests. JIT compilation will be disabled." - -AC_ARG_VAR(LLVM_CONFIG, [path to llvm-config utility]) - -AC_ARG_ENABLE([jit-debug], - AS_HELP_STRING([--enable-jit-debug], [enable debug printing of JIT IRs])) - -AS_IF([test "x$enable_jit_debug" = "xyes"], [ - AC_DEFINE(OCTAVE_JIT_DEBUG, 1, [Define to 1 for JIT debug printing.]) -]) +build_jit=false +AC_ARG_ENABLE([jit], + [AS_HELP_STRING([--enable-jit], + [(EXPERIMENTAL) enable JIT compiler])], + [if test "$enableval" = yes; then + build_jit=true + fi], + []) LLVM_CXXFLAGS= LLVM_CPPFLAGS= LLVM_LDFLAGS= LLVM_LIBS= -if test "x$ac_cv_env_LLVM_CONFIG_set" = "xset"; then - ## We use -isystem if available because we do not want to see warnings in LLVM - LLVM_INCLUDE_FLAG=-I - OCTAVE_CC_FLAG(-isystem ., [ - LLVM_INCLUDE_FLAG=-isystem - AC_MSG_NOTICE([using -isystem for llvm headers])]) +if test $build_jit = true; then + + ## Find llvm-config program from environment variable or by searching + AC_ARG_VAR([LLVM_CONFIG], [path to llvm-config utility]) + AC_CHECK_PROG([LLVM_CONFIG], llvm-config, llvm-config, []) + + if test -z "$LLVM_CONFIG"; then + warn_llvm="llvm-config utility not found. JIT compiler is disabled." + else + dnl Preset warning message in case compile fails + warn_llvm="LLVM was not found or is to old. JIT compiler is disabled." - LLVM_LDFLAGS="-L`$LLVM_CONFIG --libdir`" - LLVM_LIBS=`$LLVM_CONFIG --libs` - dnl Use -isystem so we don't get warnings from llvm headers - LLVM_CPPFLAGS="$LLVM_INCLUDE_FLAG `$LLVM_CONFIG --includedir`" - LLVM_CXXFLAGS= + save_CPPFLAGS="$CPPFLAGS" + save_CXXFLAGS="$CXXFLAGS" + + ## Use -isystem if available because we don't want to see warnings in LLVM + LLVM_INCLUDE_FLAG=-I + OCTAVE_CC_FLAG([-isystem .], [ + LLVM_INCLUDE_FLAG=-isystem + AC_MSG_NOTICE([using -isystem for LLVM headers])]) + + dnl Use -isystem so we don't get warnings from llvm headers + LLVM_CPPFLAGS="$LLVM_INCLUDE_FLAG `$LLVM_CONFIG --includedir`" + LLVM_CXXFLAGS= + LLVM_LDFLAGS="-L`$LLVM_CONFIG --libdir`" + LLVM_LIBS=`$LLVM_CONFIG --libs` - dnl - dnl We define some extra flags that LLVM requires in order to include headers. - dnl Ideally we should get these from llvm-config, but llvm-config isn't very - dnl helpful. - dnl - CPPFLAGS="-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS $LLVM_CPPFLAGS $CPPFLAGS" - CXXFLAGS="$LLVM_CXXFLAGS $CXXFLAGS" - LIBS="$LLVM_LIBS $LIBS" - LDFLAGS="$LLVM_LDFLAGS $LDFLAGS" + dnl + dnl Define some extra flags that LLVM requires in order to include headers. + dnl Ideally we should get these from llvm-config, but llvm-config isn't + dnl very helpful. + dnl + CPPFLAGS="-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS $LLVM_CPPFLAGS $CPPFLAGS" + CXXFLAGS="$LLVM_CXXFLAGS $CXXFLAGS" + AC_LANG_PUSH(C++) + AC_CHECK_HEADER([llvm/Support/TargetSelect.h], [ + warn_llvm= + XTRA_CXXFLAGS="$XTRA_CXXFLAGS $LLVM_CXXFLAGS $LLVM_CPPFLAGS"]) + AC_LANG_POP(C++) + CPPFLAGS="$save_CPPFLAGS" + CXXFLAGS="$save_CXXFLAGS" + fi - AC_LANG_PUSH(C++) - AC_CHECK_HEADER([llvm/LLVMContext.h], [ - AC_MSG_CHECKING([for llvm::getGlobalContext in llvm/LLVMContext.h]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #include <llvm/LLVMContext.h> - ]], [[ - llvm::LLVMContext& ctx = llvm::getGlobalContext (); - ]])], - [AC_MSG_RESULT([yes]) - warn_llvm= - XTRA_CXXFLAGS="$XTRA_CXXFLAGS $LLVM_CXXFLAGS $LLVM_CPPFLAGS"], - [AC_MSG_RESULT([no]) - ]) - ]) - AC_LANG_POP(C++) - -else - warn_llvm="LLVM_CONFIG not set. JIT compilation will be disabled." + if test -z "$warn_llvm"; then + AC_DEFINE(HAVE_LLVM, 1, [Define to 1 if LLVM is available.]) + else + build_jit=false + LLVM_CPPFLAGS= + LLVM_CXXFLAGS= + LLVM_LDFLAGS= + LLVM_LIBS= + OCTAVE_CONFIGURE_WARNING([warn_llvm]) + fi +dnl FIXME: Re-instate when JIT is enabled by default +dnl else +dnl ## JIT build disabled +dnl warn_llvm="JIT compiler disabled, some performance loss for loops" +dnl OCTAVE_CONFIGURE_WARNING([warn_llvm]) fi -if test -z "$warn_llvm"; then - AC_DEFINE(HAVE_LLVM, 1, [Define to 1 if LLVM is available.]) -else - LLVM_CXXFLAGS= - LLVM_CPPFLAGS= - LLVM_LDFLAGS= - LLVM_LIBS= - OCTAVE_CONFIGURE_WARNING([warn_llvm]) -fi - +AC_SUBST(LLVM_CPPFLAGS) AC_SUBST(LLVM_CXXFLAGS) -AC_SUBST(LLVM_CPPFLAGS) AC_SUBST(LLVM_LDFLAGS) AC_SUBST(LLVM_LIBS) -CPPFLAGS="$save_CPPFLAGS" -CXXFLAGS="$save_CXXFLAGS" -LIBS="$save_LIBS" -LDFLAGS="$save_LDFLAGS" - ### Check for HDF5 library. save_CPPFLAGS="$CPPFLAGS" +save_LIBS="$LIBS" CPPFLAGS="$Z_CPPFLAGS $CPPFLAGS" -save_LIBS="$LIBS" LIBS="$Z_LDFLAGS $Z_LIBS $LIBS" OCTAVE_CHECK_LIB(hdf5, HDF5, [HDF5 library not found. Octave will not be able to save or load HDF5 data files.], @@ -775,7 +752,7 @@ TEXINFO_HDF5="@set HAVE_HDF5" AC_DEFINE(HAVE_HDF5, 1, [Define to 1 if HDF5 is available and newer than version 1.6.]) - if test "$have_msvc" = "yes"; then + if test $have_msvc = yes; then OCTAVE_CHECK_LIB_HDF5_DLL fi ]) @@ -796,15 +773,15 @@ AM_CONDITIONAL([AMCOND_HAVE_FFTW], [test -n "$FFTW3_LIBS" && test -n "$FFTW3F_LIBS"]) -## Subdirectory of libcruft to build if FFTW is not found. +## Subdirectory of liboctave/cruft to build if FFTW is not found. FFT_DIR="fftpack" AC_SUBST(FFT_DIR) ### Check for GLPK library and header. save_CPPFLAGS="$CPPFLAGS" +save_LIBS="$LIBS" CPPFLAGS="$Z_CPPFLAGS $CPPFLAGS" -save_LIBS="$LIBS" LIBS="$Z_LDFLAGS $Z_LIBS $LIBS" OCTAVE_CHECK_LIB(glpk, GLPK, [GLPK library not found. The glpk function for solving linear programs will be disabled.], @@ -815,12 +792,29 @@ ### Checks for cURL header and library. save_CPPFLAGS="$CPPFLAGS" +save_LIBS="$LIBS" CPPFLAGS="$Z_CPPFLAGS $CPPFLAGS" -save_LIBS="$LIBS" LIBS="$Z_LDFLAGS $Z_LIBS $LIBS" OCTAVE_CHECK_LIB(curl, cURL, [cURL library not found. The ftp objects, urlread and urlwrite functions will be disabled.], [curl/curl.h], [curl_easy_escape]) +if test -z "$warn_curl"; then + ## Additional check on cURL library that was found + AC_CACHE_CHECK([for CURLOPT_DIRLISTONLY in curl/curl.h], + [octave_cv_header_define_curlopt_dirlistonly], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <curl/curl.h> + ]], [[ + curl_easy_setopt ((CURL*)NULL, CURLOPT_DIRLISTONLY, 0); + ]])], + [octave_cv_header_define_curlopt_dirlistonly=no], + [octave_cv_header_define_curlopt_dirlistonly=yes]) + ]) + if test $octave_cv_header_define_curlopt_dirlistonly = yes; then + AC_DEFINE(CURLOPT_DIRLISTONLY, CURLOPT_FTPLISTONLY, + [Define to the legacy option name if using an older version of cURL.])] + fi +fi LIBS="$save_LIBS" CPPFLAGS="$save_CPPFLAGS" @@ -854,22 +848,27 @@ CPPFLAGS="$MAGICK_CPPFLAGS $CPPFLAGS" LIBS="$MAGICK_LDFLAGS $MAGICK_LIBS $LIBS" AC_LANG_PUSH(C++) - AC_CHECK_HEADER([Magick++.h], [ - AC_MSG_CHECKING([for Magick::ColorRGB in Magick++.h]) - AC_PREPROC_IFELSE( - [AC_LANG_SOURCE([[ - #include <Magick++.h> - ]], [[ - Magick::ColorRGB c; - ]])], - [AC_MSG_RESULT(yes) - warn_magick=], - [AC_MSG_RESULT(no)] - ) - ]) + AC_CHECK_HEADER([Magick++.h], [ + AC_CACHE_CHECK([for Magick::ColorRGB in Magick++.h], + [octave_cv_func_magick_colorrgb], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ + #include <Magick++.h> + ]], [[ + Magick::ColorRGB c; + ]])], + octave_cv_func_magick_colorrgb=yes, + octave_cv_func_magick_colorrgb=no) + ]) + if test $octave_cv_func_magick_colorrgb = yes; then + warn_magick= + fi + ]) AC_LANG_POP(C++) CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" + + AC_CHECK_FUNCS([setlocale], [], + [warn_magick="$magick++ requires setlocale function. The imread function for reading image files will not be fully functional."]) ]) if test -z "$warn_magick"; then @@ -887,7 +886,7 @@ ### Check for X11 libraries AC_PATH_X -if test "$have_x" = "yes"; then +if test "$have_x" = yes; then AC_DEFINE(HAVE_X_WINDOWS, 1, [Define to 1 if you have X11.]) if test "$x_includes" != "NONE"; then @@ -895,20 +894,20 @@ fi AC_SUBST(X11_INCFLAGS) - if test -z $x_libraries; then - AC_CHECK_LIB(X11, XrmInitialize, [X11_LIBS=-lX11], [X11_LIBS=]) + if test -z "$x_libraries"; then + AC_CHECK_LIB([X11], XrmInitialize, [X11_LIBS="-lX11"], [X11_LIBS=]) elif test $x_libraries != "NONE"; then - AC_CHECK_LIB(X11, XrmInitialize, + AC_CHECK_LIB([X11], XrmInitialize, [X11_LIBS="-L$x_libraries -lX11"], [X11_LIBS=], "-L$x_libraries") fi AC_SUBST(X11_LIBS) fi ### Check for the Carbon framework on MacOSX systems -OCTAVE_HAVE_FRAMEWORK(Carbon, +OCTAVE_HAVE_FRAMEWORK([Carbon], [[#include <Carbon/Carbon.h>]], [[CGMainDisplayID ()]], - [have_framework_carbon="yes"], [have_framework_carbon="no"]) -if test $have_framework_carbon = "yes"; then + [have_framework_carbon=yes], [have_framework_carbon=no]) +if test $have_framework_carbon = yes; then AC_DEFINE(HAVE_FRAMEWORK_CARBON, 1, [Define to 1 if framework CARBON is available.]) CARBON_LIBS="-Wl,-framework -Wl,Carbon" @@ -918,17 +917,17 @@ ### Check for list of libraries needed for native graphics renderer. +native_graphics=true warn_freetype="" -native_graphics=true check_opengl=false AC_ARG_WITH([opengl], [AS_HELP_STRING([--without-opengl], [don't use OpenGL libraries, disable native graphics])], - [if test "x$withval" = xno; then + [if test x"$withval" = x"no"; then + native_graphics=false warn_opengl="--without-opengl specified. Native graphics will be disabled." OCTAVE_CONFIGURE_WARNING([warn_opengl]) - native_graphics=false else check_opengl=true fi], @@ -944,9 +943,9 @@ if test -z "$OPENGL_LIBS"; then if $check_opengl; then + native_graphics=false warn_fltk_opengl="OpenGL libs (GL and GLU) not found. Native graphics will be disabled." OCTAVE_CONFIGURE_WARNING([warn_fltk_opengl]) - native_graphics=false fi fi @@ -979,8 +978,8 @@ fi if test -n "$warn_fontconfig"; then + native_graphics=false OCTAVE_CONFIGURE_WARNING([warn_fontconfig]) - native_graphics=false fi ## Check for FLTK (www.fltk.org) library @@ -997,14 +996,14 @@ [fltk_exec_prefix="$withval"], [fltk_exec_prefix=""]) - if test -n "$fltk_exec_prefix"; then + if test x"$fltk_exec_prefix" != x""; then fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix" if test "x${FLTK_CONFIG+set}" != xset ; then FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config" fi fi - if test -n "$fltk_prefix"; then + if test x"$fltk_prefix" != x""; then fltk_args="$fltk_args --prefix=$fltk_prefix" if test x${FLTK_CONFIG+set} != xset ; then FLTK_CONFIG="$fltk_prefix/bin/fltk-config" @@ -1016,38 +1015,46 @@ warn_fltk_config="" warn_fltk_opengl="" - if test "$FLTK_CONFIG" = "no" ; then + if test "$FLTK_CONFIG" = no; then + native_graphics=false warn_fltk_config="FLTK config script not found. Native graphics will be disabled." OCTAVE_CONFIGURE_WARNING([warn_fltk_config]) - native_graphics=false else - FLTK_CFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`" - FLTK_LDFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`" + FLTK_CFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --cflags` + FLTK_LDFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags` - case "$canonical_host_type" in + case $canonical_host_type in *-*-mingw*) - FLTK_LDFLAGS="`echo $FLTK_LDFLAGS | sed -e 's/-mwindows//g'`" + FLTK_LDFLAGS=`echo $FLTK_LDFLAGS | sed -e 's/-mwindows//g'` ;; esac - AC_MSG_CHECKING([for OpenGL support in FLTK]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $FLTK_CFLAGS" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include <FL/gl.h>]], [[int nothing = 0;]])], - [AC_MSG_RESULT([no]) - warn_fltk_opengl="FLTK does not have OpenGL support. Native graphics will be disabled."], - [AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_FLTK, 1, [Define to 1 if FLTK is available.])]) - + AC_CACHE_CHECK([for OpenGL support in FLTK], + [octave_cv_fltk_opengl_support], + [save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $FLTK_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <FL/gl.h> + ]], [[ + int nothing = 0; + ]])], + octave_cv_fltk_opengl_support=no, + octave_cv_fltk_opengl_support=yes) + CFLAGS="$save_CFLAGS" + ]) + if test $octave_cv_fltk_opengl_support = no; then + warn_fltk_opengl="FLTK does not have OpenGL support. Native graphics will be disabled." + else + AC_DEFINE(HAVE_FLTK, 1, [Define to 1 if FLTK is available.]) + fi + if test -z "$warn_fltk_opengl"; then GRAPHICS_CFLAGS="$FLTK_CFLAGS" GRAPHICS_LIBS="$FLTK_LDFLAGS" else + native_graphics=false OCTAVE_CONFIGURE_WARNING([warn_fltk_opengl]) - native_graphics=false fi - CFLAGS="$save_CFLAGS" fi fi @@ -1057,7 +1064,7 @@ ### Start determination of shared vs. static libraries ## Use -static if compiling on Alpha OSF/1 1.3 systems. -case "$canonical_host_type" in +case $canonical_host_type in alpha*-dec-osf1.3) LD_STATIC_FLAG=-static ;; @@ -1077,20 +1084,20 @@ LT_PREREQ([2.2.2]) LT_INIT([disable-static dlopen win32-dll]) -if test x$enable_shared = xyes; then +if test x"$enable_shared" = x"yes"; then SHARED_LIBS=true else SHARED_LIBS=false fi -if test x$enable_static = xyes; then +if test x"$enable_static" = x"yes"; then STATIC_LIBS=true else STATIC_LIBS=false fi XTRA_CRUFT_SH_LDFLAGS= -if test "$have_msvc" = "yes"; then +if test $have_msvc = yes; then FLIBS="$FLIBS -lkernel32" XTRA_CRUFT_SH_LDFLAGS="-Wl,-def:cruft.def" fi @@ -1108,8 +1115,8 @@ ## Restore FFLAGS. FFLAGS="$save_FFLAGS" -## Try again with -ff2c in FFLAGS -if test "x$ax_blas_f77_func_ok" = "xno"; then +## If necessary, try again with -ff2c in FFLAGS +if test $ax_blas_f77_func_ok = no; then save_FFLAGS="$FFLAGS" FFLAGS="-ff2c $FFLAGS $F77_INTEGER_8_FLAG" @@ -1118,7 +1125,7 @@ ## Restore FFLAGS, with -ff2c if that was helpful - if test "x$ax_blas_f77_func_ok" = "xno"; then + if test $ax_blas_f77_func_ok = no; then FFLAGS="$save_FFLAGS" else FFLAGS="-ff2c $save_FFLAGS" @@ -1126,15 +1133,15 @@ fi ## On OSX, try again with a wrapper library (without -ff2c!) -if test "x$ax_blas_f77_func_ok" = "xno"; then - case "$canonical_host_type" in +if test $ax_blas_f77_func_ok = no; then + case $canonical_host_type in *-*-darwin*) ## test if wrapper functions help octave_blaswrap_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -DUSE_BLASWRAP" AC_LANG_PUSH(C) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ - #include "libcruft/misc/blaswrap.c" + #include "liboctave/cruft/misc/blaswrap.c" ]])], [mv conftest.$ac_objext blaswrap.$ac_objext octave_blaswrap_save_BLAS_LIBS="$BLAS_LIBS" @@ -1151,15 +1158,15 @@ ## remove temp file rm -f blaswrap.$ac_objext], - [AC_MSG_FAILURE([cannot compile libcruft/misc/blaswrap.c])]) + [AC_MSG_FAILURE([cannot compile liboctave/cruft/misc/blaswrap.c])]) AC_LANG_POP(C) CFLAGS="$octave_blaswrap_save_CFLAGS" - if test "x$ax_blas_f77_func_ok" = "xno"; then + if test $ax_blas_f77_func_ok = no; then BLAS_LIBS="$octave_blaswrap_save_BLAS_LIBS" else - ## wrapper in libcruft, remove from BLAS_LIBS - BLAS_LIBS="`echo $BLAS_LIBS | sed -e 's/blaswrap.[[^ ]]* //g'`" + ## wrapper in cruft, remove from BLAS_LIBS + BLAS_LIBS=`echo $BLAS_LIBS | sed -e 's/blaswrap.[[^ ]]* //g'` AC_DEFINE(USE_BLASWRAP, 1, [Define to 1 if BLAS functions need to be wrapped (potentially needed for 64-bit OSX only).]) fi @@ -1167,8 +1174,8 @@ esac fi -if test "x$ax_blas_f77_func_ok" = "xno"; then - if $USE_64_BIT_IDX_T && test "$ax_blas_integer_size_ok" = "no" ; then +if test $ax_blas_f77_func_ok = no; then + if $USE_64_BIT_IDX_T && test $ax_blas_integer_size_ok = no; then ## Attempt to be more informative. AC_MSG_ERROR([BLAS doesn't seem to support 64-bit integers. This is incompatible with --enable-64.]) else @@ -1176,7 +1183,7 @@ fi fi -if test x$ax_blas_ok = xno || test x$ax_lapack_ok = xno; then +if test $ax_blas_ok = no || test $ax_lapack_ok = no; then AC_MSG_ERROR([BLAS and LAPACK libraries are required]) fi @@ -1192,17 +1199,18 @@ [sqr1up], [Fortran 77], [don't use qrupdate, disable QR & Cholesky updating functions]) -if test "$octave_qrupdate_ok" = yes; then - LIBS="$LIBS $QRUPDATE_LIBS" - AC_LANG_PUSH([Fortran 77]) - AC_MSG_CHECKING([for slup1up in $QRUPDATE_LIBS]) - octave_qrupdate_luu=no - AC_LINK_IFELSE([AC_LANG_CALL([], [slup1up])], [octave_qrupdate_luu=yes]) - AC_MSG_RESULT([$octave_qrupdate_luu]) - if test "$octave_qrupdate_luu" = yes; then +if test $octave_cv_lib_qrupdate = yes; then + AC_CACHE_CHECK([for slup1up in $QRUPDATE_LIBS], + [octave_cv_func_slup1up], + [LIBS="$LIBS $QRUPDATE_LIBS" + AC_LANG_PUSH([Fortran 77]) + AC_LINK_IFELSE([AC_LANG_CALL([], [slup1up])], + octave_cv_func_slup1up=yes, octave_cv_func_slup1up=no) + AC_LANG_POP([Fortran 77]) + ]) + if test $octave_cv_func_slup1up = yes; then AC_DEFINE(HAVE_QRUPDATE_LUU, 1, [Define to 1 if qrupdate supports LU updates.]) fi - AC_LANG_POP([Fortran 77]) fi LIBS="$save_LIBS" @@ -1238,8 +1246,9 @@ [ccolamd], [], [don't use CCOLAMD library, disable some sparse matrix functionality]) -### Check for CHOLMOD library. If your cholmod library requires cblas, -### then you will need to configure with --with-cholmod="-lcholmod -lcblas". +### Check for CHOLMOD library. +### If your cholmod library requires cblas, then you will need to +### configure with --with-cholmod="-lcholmod -lcblas". save_LIBS="$LIBS" LIBS="$COLAMD_LDFLAGS $COLAMD_LIBS $AMD_LDFLAGS $AMD_LIBS $LAPACK_LIBS $BLAS_LIBS $FLIBS $LIBS" @@ -1264,7 +1273,7 @@ save_CPPFLAGS="$CPPFLAGS" LIBS="$AMD_LDFLAGS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS" CPPFLAGS="$AMD_CPPFLAGS $CPPFLAGS" -OCTAVE_CHECK_LIB(umfpack, UMFPACK, +OCTAVE_CHECK_LIB([umfpack], UMFPACK, [UMFPACK not found. This will result in some lack of functionality for sparse matrices.], [suitesparse/umfpack.h ufsparse/umfpack.h umfpack/umfpack.h umfpack.h], [umfpack_zi_get_determinant], @@ -1275,9 +1284,10 @@ if test -z "$UMFPACK_LIBS"; then ## Invalidate the cache and try again with -lcblas. $as_unset ac_cv_lib_umfpack_umfpack_zi_get_determinant + $as_unset octave_cv_lib_umfpack save_LIBS="$LIBS" LIBS="-lcblas $AMD_LDFLAGS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS" - OCTAVE_CHECK_LIB(umfpack, UMFPACK, + OCTAVE_CHECK_LIB([umfpack], UMFPACK, [UMFPACK not found. This will result in some lack of functionality for sparse matrices.], [suitesparse/umfpack.h ufsparse/umfpack.h umfpack/umfpack.h umfpack.h], [umfpack_zi_get_determinant], @@ -1288,18 +1298,48 @@ LIBS="$save_LIBS" fi +## Test features of the installed UMFPACK library + if test -n "$UMFPACK_LIBS"; then + ## SuiteSparse >= 4.0 needs additional link library for SuiteSparse_time() save_LIBS="$LIBS"; - LIBS="$UMFPACK_LIBS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS" - OCTAVE_UMFPACK_SEPARATE_SPLIT + LIBS="$UMFPACK_LIBS $AMD_LDFLAGS $AMD_LIBS $BLAS_LIBS $FLIBS $LIBS" + xtra_libs= + OCTAVE_UMFPACK_NEED_SUITESPARSE_TIME + if test $octave_cv_umfpack_need_suitesparse_time = yes; then + AC_CHECK_LIB([rt], [clock_gettime], [xtra_libs="-lrt"], [xtra_libs=]) + ## FIXME: This library list is only accurate for Linux, Mac OS X. + ## Possibly need other library names for MinGW, Cygwin. + AC_SEARCH_LIBS([SuiteSparse_time], + [suitesparseconfig SuiteSparse], + [], [], [$xtra_libs]) + case $ac_cv_search_SuiteSparse_time in + -l*) + UMFPACK_LIBS="$UMFPACK_LIBS $ac_cv_search_SuiteSparse_time" + ;; + no) + UMFPACK_LIBS= + AC_MSG_WARN([UMFPACK library found but is missing SuiteSparse_time functionality.]) + AC_MSG_WARN([UMFPACK library will be disabled.]) + ;; + esac + fi LIBS="$save_LIBS" + + ## Check for UMFPACK separately split complex matrix and RHS. + if test -n "$UMFPACK_LIBS"; then + save_LIBS="$LIBS"; + LIBS="$UMFPACK_LIBS $CHOLMOD_LDFLAGS $CHOLMOD_LIBS $AMD_LDFLAGS $AMD_LIBS $COLAMD_LDFLAGS $COLAMD_LIBS $LAPACK_LIBS $BLAS_LIBS $FLIBS $LIBS $xtra_libs" + OCTAVE_UMFPACK_SEPARATE_SPLIT + LIBS="$save_LIBS" + fi fi ### Check for ARPACK library. save_LIBS="$LIBS" LIBS="$LAPACK_LIBS $BLAS_LIBS $FLIBS $LIBS" -OCTAVE_CHECK_LIB(arpack, ARPACK, +OCTAVE_CHECK_LIB([arpack], ARPACK, [ARPACK not found. The eigs function will be disabled.], [], [dseupd], @@ -1320,12 +1360,12 @@ ### example, OS X and Windows). AC_ARG_ENABLE([dl], - [AS_HELP_STRING([--enable-dl], - [allow loading of dynamically linked modules (not all systems)])], - [case "${enableval}" in + [AS_HELP_STRING([--disable-dl], + [disable loading of dynamically linked modules])], + [case $enableval in yes) ENABLE_DYNAMIC_LINKING=true ;; no) ENABLE_DYNAMIC_LINKING=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-dl]) ;; + *) AC_MSG_ERROR([bad value $enableval for --enable-dl]) ;; esac], [ENABLE_DYNAMIC_LINKING=true]) @@ -1361,11 +1401,12 @@ CRUFT_DLL_DEFS= OCTAVE_DLL_DEFS= OCTINTERP_DLL_DEFS= +OCTGUI_DLL_DEFS= OCTGRAPHICS_DLL_DEFS= library_path_var=LD_LIBRARY_PATH ldpreloadsep=" " BUILD_COMPILED_AUX_PROGRAMS=false -case "$canonical_host_type" in +case $canonical_host_type in *-*-386bsd* | *-*-netbsd*) SH_LD=ld SH_LDFLAGS=-Bshareable @@ -1386,7 +1427,7 @@ DL_LDFLAGS='-bundle -bundle_loader $(top_builddir)/libinterp/octave $(LDFLAGS)' MKOCTFILE_DL_LDFLAGS='-bundle -bundle_loader $$BINDIR/octave-$$OCTAVE_VERSION$$EXEEXT' SH_LDFLAGS='-dynamiclib -single_module $(LDFLAGS)' - case "$canonical_host_type" in + case $canonical_host_type in powerpc-*) CXXPICFLAG= CPICFLAG= @@ -1418,7 +1459,7 @@ ;; *-*-mingw*) BUILD_COMPILED_AUX_PROGRAMS=true - if test "$have_msvc" = "yes"; then + if test $have_msvc = yes; then DL_LDFLAGS="-shared" CPICFLAG= CXXPICFLAG= @@ -1431,7 +1472,7 @@ SHLLIBPRE= SHLBINPRE= SH_LDFLAGS="-shared" - if test -n "`echo $CFLAGS | grep -e '-g'`" -o -n "`echo $CXXFLAGS | grep -e '-g'`"; then + if test -n "`echo $CFLAGS | grep -e '-g'`" || test -n "`echo $CXXFLAGS | grep -e '-g'`"; then DL_LDFLAGS="$DL_LDFLAGS -g" SH_LDFLAGS="$SH_LDFLAGS -g" fi @@ -1442,6 +1483,7 @@ CRUFT_DLL_DEFS="-DCRUFT_DLL" OCTAVE_DLL_DEFS="-DOCTAVE_DLL" OCTINTERP_DLL_DEFS="-DOCTINTERP_DLL" + OCTGUI_DLL_DEFS="-DOCTGUI_DLL" OCTGRAPHICS_DLL_DEFS="-DOCTGRAPHICS_DLL" else CPICFLAG= @@ -1471,7 +1513,7 @@ SHLLIBPRE= SHLBINPRE= SH_LDFLAGS="-shared" - if test -n "`echo $CFLAGS | grep -e '-g'`" -o -n "`echo $CXXFLAGS | grep -e '-g'`"; then + if test -n "`echo $CFLAGS | grep -e '-g'`" || test -n "`echo $CXXFLAGS | grep -e '-g'`"; then DL_LDFLAGS="$DL_LDFLAGS -g" SH_LDFLAGS="$SH_LDFLAGS -g" fi @@ -1481,7 +1523,7 @@ ## Extra compilation flags. CRUFT_DLL_DEFS="-DCRUFT_DLL" OCTAVE_DLL_DEFS="-DOCTAVE_DLL" - OCTINTERP_DLL_DEFS="-DOCTINTERP_DLL" + OCTGUI_DLL_DEFS="-DOCTGUI_DLL" OCTGRAPHICS_DLL_DEFS="-DOCTGRAPHICS_DLL" ;; *-*-linux* | *-*-gnu*) @@ -1499,7 +1541,7 @@ library_path_var=LIBPATH ;; hppa*-hp-hpux*) - if test "$ac_cv_f77_compiler_gnu" = yes; then + if test $ac_cv_f77_compiler_gnu = yes; then FPICFLAG=-fPIC else FPICFLAG=+Z @@ -1509,7 +1551,7 @@ library_path_var=SHLIB_PATH ;; ia64*-hp-hpux*) - if test "$ac_cv_f77_compiler_gnu" = yes; then + if test $ac_cv_f77_compiler_gnu = yes; then FPICFLAG=-fPIC else FPICFLAG=+Z @@ -1522,7 +1564,7 @@ FPICFLAG= ;; sparc-sun-sunos4*) - if test "$ac_cv_f77_compiler_gnu" = yes; then + if test $ac_cv_f77_compiler_gnu = yes; then FPICFLAG=-fPIC else FPICFLAG=-PIC @@ -1531,7 +1573,7 @@ SH_LDFLAGS="-assert nodefinitions" ;; sparc-sun-solaris2* | i386-pc-solaris2*) - if test "$ac_cv_f77_compiler_gnu" = yes; then + if test $ac_cv_f77_compiler_gnu = yes; then FPICFLAG=-fPIC else FPICFLAG=-KPIC @@ -1549,9 +1591,7 @@ SH_LDFLAGS=-G fi ## Template closures in archive libraries need a different mechanism. - if test "$GXX" = yes; then - true - else + if test "$GXX" != yes; then TEMPLATE_AR='$(CXX)' TEMPLATE_ARFLAGS="-xar -o" fi @@ -1587,6 +1627,7 @@ AC_MSG_NOTICE([defining CRUFT_DLL_DEFS to be $CRUFT_DLL_DEFS]) AC_MSG_NOTICE([defining OCTAVE_DLL_DEFS to be $OCTAVE_DLL_DEFS]) AC_MSG_NOTICE([defining OCTINTERP_DLL_DEFS to be $OCTINTERP_DLL_DEFS]) +AC_MSG_NOTICE([defining OCTGUI_DLL_DEFS to be $OCTGUI_DLL_DEFS]) AC_MSG_NOTICE([defining OCTGRAPHICS_DLL_DEFS to be $OCTGRAPHICS_DLL_DEFS]) AC_MSG_NOTICE([defining library_path_var to be $library_path_var]) AC_SUBST(FPICFLAG) @@ -1615,6 +1656,7 @@ AC_SUBST(CRUFT_DLL_DEFS) AC_SUBST(OCTAVE_DLL_DEFS) AC_SUBST(OCTINTERP_DLL_DEFS) +AC_SUBST(OCTGUI_DLL_DEFS) AC_SUBST(OCTGRAPHICS_DLL_DEFS) AC_SUBST(library_path_var) AC_SUBST(ldpreloadsep) @@ -1622,12 +1664,12 @@ ### More configure argument checking related to linking AC_ARG_ENABLE([no-undefined], - [AS_HELP_STRING([--enable-no-undefined], - [pass -no-undefined to libtool when linking Octave and its shared libraries (on by default)])], - [case "${enableval}" in + [AS_HELP_STRING([--disable-no-undefined], + [don't pass -no-undefined to libtool when linking Octave and its shared libraries])], + [case $enableval in yes) NO_UNDEFINED_LDFLAG="-no-undefined" ;; no) NO_UNDEFINED_LDFLAG="" ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-link-all-depenencies]) ;; + *) AC_MSG_ERROR([bad value $enableval for --disable-no-undefined]) ;; esac], [NO_UNDEFINED_LDFLAG="-no-undefined"]) AC_SUBST(NO_UNDEFINED_LDFLAG) @@ -1635,13 +1677,14 @@ AC_ARG_ENABLE([link-all-dependencies], [AS_HELP_STRING([--enable-link-all-dependencies], [link Octave and its shared libraries with all dependencies, not just those immediately referenced (should not be needed on most systems)])], - [case "${enableval}" in + [case $enableval in yes) link_all_deps=true ;; no) link_all_deps=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-link-all-depenencies]) ;; + *) AC_MSG_ERROR([bad value $enableval for --enable-link-all-depenencies]) + ;; esac], [link_all_deps=false]) -AM_CONDITIONAL([AMCOND_LINK_ALL_DEPS], [test x$link_all_deps = xtrue]) +AM_CONDITIONAL([AMCOND_LINK_ALL_DEPS], [test $link_all_deps = true]) ## Dynamic linking is now enabled only if we are building shared ## libs and some API for dynamic linking has been detected. @@ -1659,13 +1702,13 @@ if $SHARED_LIBS || $ENABLE_DYNAMIC_LINKING; then - case "$lt_cv_dlopen" in + case $lt_cv_dlopen in dlopen) dlopen_api=true DL_API_MSG="(dlopen)" AC_DEFINE(HAVE_DLOPEN_API, 1, [Define to 1 if your system has dlopen, dlsym, dlerror, and dlclose for dynamic linking.]) - OCTAVE_CXX_FLAG(-rdynamic, [RDYNAMIC_FLAG=-rdynamic]) + OCTAVE_CXX_FLAG([-rdynamic], [RDYNAMIC_FLAG=-rdynamic]) ;; shl_load) shl_load_api=true @@ -1703,16 +1746,14 @@ fi AM_CONDITIONAL([AMCOND_ENABLE_DYNAMIC_LINKING], - [test x$ENABLE_DYNAMIC_LINKING = xtrue]) + [test x"$ENABLE_DYNAMIC_LINKING" = x"true"]) if $SHARED_LIBS; then - LIBOCTINTERP=-loctinterp$SHLLINKEXT - LIBOCTAVE=-loctave$SHLLINKEXT - LIBCRUFT=-lcruft$SHLLINKEXT + LIBOCTINTERP="-loctinterp$SHLLINKEXT" + LIBOCTAVE="-loctave$SHLLINKEXT" else LIBOCTINTERP='$(top_builddir)/libinterp/liboctinterp.$(LIBEXT)' LIBOCTAVE='$(top_builddir)/liboctave/liboctave.$(LIBEXT)' - LIBCRUFT='$(top_builddir)/libcruft/libcruft.$(LIBEXT)' fi AC_SUBST(LD_CXX) @@ -1720,15 +1761,14 @@ AC_SUBST(ENABLE_DYNAMIC_LINKING) AC_SUBST(LIBOCTINTERP) AC_SUBST(LIBOCTAVE) -AC_SUBST(LIBCRUFT) ### Check for existence of various libraries ## OS-specific test for dirent, opendir. -case "$canonical_host_type" in +case $canonical_host_type in *-*-mingw*) - if test "$have_msvc" = "yes"; then - AC_CHECK_LIB(dirent, opendir) + if test $have_msvc = yes; then + AC_CHECK_LIB([dirent], [opendir]) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" else LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32" @@ -1736,83 +1776,53 @@ LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32" ;; *-*-msdosmsvc*) - AC_CHECK_LIB(dirent, opendir) + AC_CHECK_LIB([dirent], [opendir]) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" ;; esac ## Find a termlib to use. -octave_found_termlib=no -for termlib in ncurses curses termcap terminfo termlib; do - AC_CHECK_LIB(${termlib}, tputs, [ - TERM_LIBS="-l${termlib}" - octave_found_termlib=yes - break]) -done - -if test "$octave_found_termlib" = no; then - warn_termlibs="I couldn't find -ltermcap, -lterminfo, -lncurses, -lcurses, o\ -r -ltermlib!" - AC_MSG_WARN([$warn_termlibs]) -fi -AC_SUBST(TERM_LIBS) +OCTAVE_CHECK_LIB_TERMLIB ### Checks for header files. AC_HEADER_DIRENT AC_HEADER_SYS_WAIT -dnl FIXME: We should probably only generate this file if it is missing. -### Produce unistd.h for MSVC target, this simplifies changes in -### Octave source tree and avoid problems with lex-generated code. -case "$canonical_host_type" in - *-*-msdosmsvc) - AC_MSG_NOTICE([Generating replacement for <unistd.h> for MSVC]) - cat << \EOF > unistd.h -/* File generated by configure script. */ -#include <direct.h> -#include <io.h> -#include <process.h> -EOF - CPPFLAGS="-I. $CPPFLAGS" - ;; -esac - ## C headers -AC_CHECK_HEADERS(curses.h direct.h dlfcn.h floatingpoint.h grp.h \ - ieeefp.h inttypes.h locale.h memory.h ncurses.h poll.h pthread.h \ - pwd.h sunmath.h sys/ioctl.h sys/param.h sys/poll.h sys/resource.h \ - sys/select.h sys/utsname.h termcap.h) +dnl Use multiple AC_CHECKs to avoid line continuations '\' in list +AC_CHECK_HEADERS([curses.h direct.h dlfcn.h floatingpoint.h grp.h]) +AC_CHECK_HEADERS([ieeefp.h inttypes.h locale.h memory.h ncurses.h]) +AC_CHECK_HEADERS([poll.h pthread.h pwd.h sunmath.h sys/ioctl.h]) +AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/resource.h ]) +AC_CHECK_HEADERS([sys/select.h sys/utsname.h termcap.h]) ## C++ headers AC_LANG_PUSH(C++) -AC_CHECK_HEADERS(sstream) +AC_CHECK_HEADERS([sstream]) OCTAVE_UNORDERED_MAP_HEADERS AC_LANG_POP(C++) ## Find a termio header to include. -have_termios_h=no -AC_CHECK_HEADERS(termios.h, have_termios_h=yes) -AC_CHECK_HEADERS(termio.h, have_termio_h=yes, have_termio_h=no) -AC_CHECK_HEADERS(sgtty.h, have_sgtty_h=yes, have_sgtty_h=no) -AC_CHECK_HEADERS(fnmatch.h, have_fnmatch_h=yes, have_fnmatch_h=no) -AC_CHECK_HEADERS(conio.h, have_conio_h=yes, have_conio_h=no) +AC_CHECK_HEADERS([termios.h], have_termios_h=yes, have_termios_h=no) +AC_CHECK_HEADERS([termio.h], have_termio_h=yes, have_termio_h=no) +AC_CHECK_HEADERS([sgtty.h], have_sgtty_h=yes, have_sgtty_h=no) +AC_CHECK_HEADERS([fnmatch.h], have_fnmatch_h=yes, have_fnmatch_h=no) +AC_CHECK_HEADERS([conio.h], have_conio_h=yes, have_conio_h=no) -if test "$have_termios_h" = yes \ - || test "$have_termio_h" = yes \ - || test "$have_sgtty_h" = yes; then - true -else +if test $have_termios_h != yes \ + && test $have_termio_h != yes \ + && test $have_sgtty_h != yes; then AC_MSG_WARN([I couldn't find termios.h, termio.h, or sgtty.h!]) fi ## For MSVC compilers, avoid #define of min/max from windows.h header -if test "$have_msvc" = "yes"; then +if test $have_msvc = yes; then AC_DEFINE(NOMINMAX, 1, [Define to 1 if you want to avoid min/max macro definition in Windows headers.]) fi @@ -1833,16 +1843,17 @@ ## How big are ints and how are they oriented? ## These could probably be eliminated in favor of run-time checks. -AC_CHECK_SIZEOF(short) -AC_CHECK_SIZEOF(int) -AC_CHECK_SIZEOF(long) -AC_CHECK_SIZEOF(long long) +AC_CHECK_SIZEOF([short]) +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long]) +AC_CHECK_SIZEOF([long long]) ## Check for long double type (for 64-bit integers) -AC_CHECK_SIZEOF(long double) +AC_CHECK_SIZEOF([long double]) ### Check structures and existence of necessary members -AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks, struct stat.st_rdev]) +AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks, + struct stat.st_rdev]) AC_CHECK_MEMBERS([struct group.gr_passwd]) AC_STRUCT_TIMEZONE @@ -1893,17 +1904,24 @@ ### Checks for functions and variables. -AC_CHECK_FUNCS(basename canonicalize_file_name \ - chmod dup2 endgrent endpwent execvp expm1 expm1f fork \ - getegid geteuid getgid getgrent getgrgid getgrnam getpgrp getpid \ - getppid getpwent getpwuid getuid getwd _kbhit kill \ - lgamma lgammaf lgamma_r lgammaf_r localtime_r log1p log1pf \ - mkstemp pipe putenv \ - realpath resolvepath rindex roundl select setgrent setlocale \ - setpwent setvbuf siglongjmp \ - strsignal tempnam tgammaf umask \ - uname utime waitpid \ - _chmod x_utime _utime32) +dnl These checks define/undefine HAVE_FUNCNAME in config.h. +dnl Code tests HAVE_FUNCNAME and either uses function or provides workaround. +dnl Use multiple AC_CHECKs to avoid line continuations '\' in list +AC_CHECK_FUNCS([canonicalize_file_name dup2]) +AC_CHECK_FUNCS([endgrent endpwent execvp expm1 expm1f fork]) +AC_CHECK_FUNCS([getegid geteuid getgid getgrent getgrgid getgrnam]) +AC_CHECK_FUNCS([getpgrp getpid getppid getpwent getpwuid getuid]) +AC_CHECK_FUNCS([kill lgamma lgammaf lgamma_r lgammaf_r]) +AC_CHECK_FUNCS([log1p log1pf pipe]) +AC_CHECK_FUNCS([realpath resolvepath roundl]) +AC_CHECK_FUNCS([select setgrent setpwent siglongjmp strsignal]) +AC_CHECK_FUNCS([tempnam tgammaf toascii]) +AC_CHECK_FUNCS([umask uname waitpid]) +AC_CHECK_FUNCS([_kbhit]) + +dnl There are no workarounds in the code for missing these functions. +AC_CHECK_FUNCS([modf pow sqrt sqrtf], [], + [AC_MSG_ERROR([Missing function required to build Octave])]) ## exp2, round, tgamma function checks AC_LANG_PUSH(C++) @@ -1934,9 +1952,9 @@ OCTAVE_CHECK_FUNC_CMATH(isinf) OCTAVE_CHECK_FUNC_CMATH(isfinite) -dnl Would like to get rid of this cruft, and just have +dnl Would like to get rid of this crap, and just have dnl -dnl AC_CHECK_FUNCS(finite isnan isinf) +dnl AC_CHECK_FUNCS([finite isnan isinf]) dnl dnl instead, but that used to fail on some systems... dnl @@ -1947,50 +1965,24 @@ ### I am told that Inf and NaN don't work on m68k HP sytems. -case "$canonical_host_type" in +case $canonical_host_type in m68k-hp-hpux*) ;; *) - AC_CHECK_FUNCS(finite isnan isinf signbit) - AC_CHECK_FUNCS(_finite _isnan) - AC_CHECK_DECLS(signbit, , , [#include <math.h>]) + AC_CHECK_FUNCS([finite isnan isinf signbit]) + AC_CHECK_FUNCS([_finite _isnan]) + AC_CHECK_DECLS([signbit], , , [#include <math.h>]) ;; esac ## Check for nonstandard, but common math functions, that we need. -AC_CHECK_FUNCS(acosh acoshf asinh asinhf atanh atanhf cbrt cbrtf erf erff \ - erfc erfcf exp2f hypotf _hypotf log2 log2f) - -## MinGW exception for mkstemp -case "$canonical_host_type" in - *-*-mingw*) - ## MinGW does not provide a mkstemp function. However, it provides - ## the mkstemps function in libiberty. - AC_MSG_CHECKING([for mkstemps in libiberty]) - save_LIBS="$LIBS" - LIBS="-liberty $LIBS" - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[ - int mkstemps (char *pattern, int suffix_len); - ]], [[ - mkstemps ("XXXXXX", 0); - ]] - )], - [AC_MSG_RESULT(yes) - HAVE_MKSTEMPS=yes - AC_DEFINE(HAVE_MKSTEMPS, 1, - [Define to 1 if mkstemps is available in libiberty.]) - ], - [AC_MSG_RESULT(no) - HAVE_MKSTEMPS=no - LIBS="$save_LIBS" - ]) - ;; -esac +dnl Use multiple AC_CHECKs to avoid line continuations '\' in list +AC_CHECK_FUNCS([acosh acoshf asinh asinhf atanh atanhf cbrt cbrtf]) +AC_CHECK_FUNCS([erf erff erfc erfcf exp2f hypotf _hypotf log2 log2f]) ## Windows-specific tests for extra #defines -case "$canonical_host_type" in +case $canonical_host_type in *-*-msdosmsvc | *-*-mingw*) AC_MSG_CHECKING([for required _WIN32_WINNT]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -2015,9 +2007,17 @@ ;; esac +## Windows-specific use of functions +case $canonical_host_type in + *-*-mingw* | *-*-msdosmsvc*) + AC_CHECK_FUNCS([setvbuf], [], + [AC_MSG_ERROR([Missing function required to build Octave])]) + ;; +esac + ## Cygwin kluge for getrusage. -AC_CHECK_FUNCS(getrusage) -case "$canonical_host_type" in +AC_CHECK_FUNCS([getrusage]) +case $canonical_host_type in *-*-cygwin*) AC_DEFINE(RUSAGE_TIMES_ONLY, 1, [Define to 1 if your struct rusage only has time information.]) @@ -2025,11 +2025,11 @@ esac ## Check for CGDisplayBitsPerPixel function on Mac OSX systems with Carbon -if test $have_framework_carbon = "yes"; then +if test $have_framework_carbon = yes; then OCTAVE_CARBON_CGDISPLAYBITSPERPIXEL fi -AC_CHECK_FUNCS(getpwnam, [], [AC_CHECK_LIB(sun, getpwnam)]) +AC_CHECK_FUNCS([getpwnam], [], [AC_CHECK_LIB([sun], [getpwnam])]) AC_FUNC_CLOSEDIR_VOID @@ -2046,7 +2046,7 @@ octave_cv_func_matherr_type=yes, octave_cv_func_matherr_type=no) ]) -if test $octave_cv_func_matherr_type = "yes"; then +if test $octave_cv_func_matherr_type = yes; then AC_DEFINE(EXCEPTION_IN_MATH, 1, [Define to 1 if math.h declares struct exception for matherr().]) fi @@ -2125,9 +2125,9 @@ try_extra_warning_flags=true -AC_ARG_ENABLE(extra-warning-flags, - [AS_HELP_STRING([--enable-extra-warning-flags], - [add -Wall, -W, -Wshadow, and -Wold-style-cast options to CFLAGS and CXXFLAGS (on by default, but only if the compiler appears to accept them)])], +AC_ARG_ENABLE([extra-warning-flags], + [AS_HELP_STRING([--disable-extra-warning-flags], + [don't add -Wall, -W, -Wshadow, and -Wold-style-cast options to CFLAGS and CXXFLAGS])], [if test "$enableval" = no; then try_extra_warning_flags=false fi], @@ -2135,12 +2135,12 @@ if $try_extra_warning_flags; then for flag in $GCC_EXTRA_FLAGS; do - OCTAVE_CC_FLAG($flag, [ + OCTAVE_CC_FLAG([$flag], [ WARN_CFLAGS="$WARN_CFLAGS $flag"; AC_MSG_RESULT([adding $flag to WARN_CFLAGS])]) done for flag in $GXX_EXTRA_FLAGS; do - OCTAVE_CXX_FLAG($flag, [ + OCTAVE_CXX_FLAG([$flag], [ WARN_CXXFLAGS="$WARN_CXXFLAGS $flag"; AC_MSG_RESULT([adding $flag to WARN_CXXFLAGS])]) done @@ -2152,9 +2152,9 @@ try_strict_warning_flags=false -AC_ARG_ENABLE(strict-warning-flags, +AC_ARG_ENABLE([strict-warning-flags], [AS_HELP_STRING([--enable-strict-warning-flags], - [add extra strict warning options to CFLAGS and CXXFLAGS (off by default)])], + [add extra strict warning options to CFLAGS and CXXFLAGS])], [if test "$enableval" = yes; then try_strict_warning_flags=true fi], @@ -2162,12 +2162,12 @@ if $try_strict_warning_flags; then for flag in $GCC_STRICT_FLAGS; do - OCTAVE_CC_FLAG($flag, [ + OCTAVE_CC_FLAG([$flag], [ WARN_CFLAGS="$WARN_CFLAGS $flag"; AC_MSG_RESULT([adding $flag to WARN_CFLAGS])]) done for flag in $GXX_STRICT_FLAGS; do - OCTAVE_CXX_FLAG($flag, [ + OCTAVE_CXX_FLAG([$flag], [ WARN_CXXFLAGS="$WARN_CXXFLAGS $flag"; AC_MSG_RESULT([adding $flag to WARN_CXXFLAGS])]) done @@ -2181,40 +2181,99 @@ HAVE_QT=false QT_INCDIR= QT_LIBDIR= -build_gui=yes win32_terminal=no -AC_ARG_ENABLE(gui, - [AS_HELP_STRING([--disable-gui], [build GUI (default is yes)])], - [if test "$enableval" = no; then build_gui=no; fi], [build_gui=yes]) +build_gui=true +GUIDIR=libgui +AC_ARG_ENABLE([gui], + [AS_HELP_STRING([--disable-gui], [don't build the GUI])], + [if test "$enableval" = no; then build_gui=false; fi], []) -if test $build_gui = yes; then - AC_CHECK_PROGS(QMAKE, [qmake qmake-qt4 qmake-qt5]) - if test -n "$QMAKE"; then - QT_INCDIR=`$QMAKE -query | sed -n -e 's/^QT_INSTALL_HEADERS://p'` - QT_LIBDIR=`$QMAKE -query | sed -n -e 's/^QT_INSTALL_LIBS://p'` - AC_CHECK_PROGS(MOC, [moc moc-qt4 moc-qt5]) - AC_CHECK_PROGS(UIC, [uic uic-qt4 uic-qt5]) - AC_CHECK_PROGS(RCC, [rcc]) - if test -n "$MOC" && test -n "$UIC" && test -n "$RCC"; then - HAVE_QT=true - AC_DEFINE(HAVE_QT, 1, - [Define to 1 if Qt is available (must have moc, uic, and rcc programs and developer header files and libraries installed).]) - fi +if test $build_gui = true; then + ## Check for Qt libraries + PKG_CHECK_MODULES(QT, [QtCore, QtGui, QtNetwork], + [], + [AC_MSG_ERROR([Qt libraries are required to build the GUI])]) + + ## Check for Qt utility programs + AC_CHECK_PROGS(QMAKE, [qmake-qt5 qmake-qt4 qmake]) + if test -z "$QMAKE"; then + AC_MSG_ERROR([qmake is required to build the GUI]) + fi + + QT_INCDIR=`$QMAKE -query QT_INSTALL_HEADERS | sed -e 's,\\\\,/,g'` + QT_LIBDIR=`$QMAKE -query QT_INSTALL_LIBS | sed -e 's,\\\\,/,g'` + + if test "$QT_INCDIR" = "**Unknown**"; then + AC_MSG_ERROR([qmake >= Qt4 is required to build the GUI]) fi - case "$canonical_host_type" in - *-*-mingw* | *-*-msdosmsvc*) win32_terminal=yes ;; + AC_CHECK_PROGS(MOC, [moc-qt5 moc-qt4 moc]) + AC_CHECK_PROGS(UIC, [uic-qt5 uic-qt4 uic]) + AC_CHECK_PROGS(RCC, [rcc]) + if test -z "$MOC" || test -z "$UIC" || test -z "$RCC"; then + AC_MSG_ERROR([Qt utility programs moc, uic, and rcc are required to build the GUI]) + fi + + HAVE_QT=true + AC_DEFINE(HAVE_QT, 1, + [Define to 1 if Qt is available (libraries, developer header files, utility programs (qmake, moc, uic, and rcc))]) + + ## Check for Qscintilla library which is used in the GUI editor. + AC_CACHE_CHECK([whether Qscintilla library is installed], + [octave_cv_lib_qscintilla], + [save_CPPFLAGS="$CPPFLAGS" + save_LDFLAGS="$LDFLAGS" + save_LIBS="$LIBS" + CPPFLAGS="-I$QT_INCDIR -I$QT_INCDIR/Qt $CPPFLAGS" + LDFLAGS="-L$QT_LIBDIR $LDFLAGS" + LIBS="-lqscintilla2" + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include <Qsci/qscilexersql.h> + ]], [[ + QsciLexerSQL sqlLexer(0); + ]])], + octave_cv_lib_qscintilla=yes, + octave_cv_lib_qscintilla=no) + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + AC_LANG_POP([C++]) + ]) + if test $octave_cv_lib_qscintilla = no; then + AC_MSG_ERROR([Qscintilla library is required to build the GUI]) + fi + + ## Check for Qt functions which have changed their API over time + OCTAVE_CHECK_FUNC_FINDFIRST_MODERN + OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT + + AC_CHECK_FUNCS([setlocale], [], + [AC_MSG_ERROR([Missing function required to build GUI])]) + + case $canonical_host_type in + *-*-mingw* | *-*-msdosmsvc*) + win32_terminal=yes + AC_CHECK_FUNCS([setvbuf], [], + [AC_MSG_ERROR([Missing function required to build GUI])]) + ;; *) AC_CHECK_HEADERS([pty.h libutil.h util.h]) AC_SEARCH_LIBS([openpty], [util], [AC_DEFINE(HAVE_OPENPTY, [], [Define whether openpty exists])]) + AC_CHECK_FUNCS([chmod chown ftruncate mmap munmap], [], + [AC_MSG_ERROR([Missing function required to build GUI])]) ;; esac +else + ## GUI disabled. Eliminate building GUIDIR directory + GUIDIR= fi -AM_CONDITIONAL([AMCOND_BUILD_GUI], [test $build_gui = yes]) +AM_CONDITIONAL([AMCOND_BUILD_GUI], [test $build_gui = true]) AM_CONDITIONAL([WIN32_TERMINAL], [test $win32_terminal = yes]) AC_SUBST(QT_INCDIR) AC_SUBST(QT_LIBDIR) +AC_SUBST(GUIDIR) ### Run configure in subdirectories. @@ -2254,11 +2313,11 @@ #define FCN_PTR_CAST(T, E) reinterpret_cast<T> (E) #endif -#if !defined(HAVE_DEV_T) +#if ! defined (HAVE_DEV_T) typedef short dev_t; #endif -#if !defined(HAVE_INO_T) +#if ! defined (HAVE_INO_T) typedef unsigned long ino_t; #endif @@ -2369,6 +2428,13 @@ #define OCTGRAPHICS_API OCTAVE_IMPORT #endif +/* API macro for libgui */ +#ifdef OCTGUI_DLL +#define OCTGUI_API OCTAVE_EXPORT +#else +#define OCTGUI_API OCTAVE_IMPORT +#endif + /* oct-types.h */ typedef OCTAVE_IDX_TYPE octave_idx_type; @@ -2390,19 +2456,17 @@ AC_CONFIG_FILES([ Makefile doc/Makefile - doc/faq/Makefile doc/icons/Makefile doc/interpreter/Makefile doc/liboctave/Makefile doc/refcard/Makefile examples/Makefile - libcruft/Makefile - libcruft/mkf77def libgnu/Makefile libgui/Makefile - libgui/src/Makefile libinterp/Makefile liboctave/Makefile + liboctave/cruft/Makefile + liboctave/cruft/mkf77def scripts/Makefile src/Makefile test/Makefile]) @@ -2482,12 +2546,16 @@ QHULL CPPFLAGS: $QHULL_CPPFLAGS QHULL LDFLAGS: $QHULL_LDFLAGS QHULL libraries: $QHULL_LIBS + QRUPDATE CPPFLAGS: $QRUPDATE_CPPFLAGS + QRUPDATE LDFLAGS: $QRUPDATE_LDFLAGS QRUPDATE libraries: $QRUPDATE_LIBS Qt headers: $QT_INCDIR Qt libraries: $QT_LIBDIR READLINE libraries: $READLINE_LIBS REGEX libraries: $REGEX_LIBS TERM libraries: $TERM_LIBS + UMFPACK CPPFLAGS: $UMFPACK_CPPFLAGS + UMFPACK LDFLAGS: $UMFPACK_LDFLAGS UMFPACK libraries: $UMFPACK_LIBS X11 include flags: $X11_INCFLAGS X11 libraries: $X11_LIBS @@ -2498,6 +2566,8 @@ Default pager: $DEFAULT_PAGER gnuplot: $GNUPLOT + Build Octave GUI: $build_gui + JIT compiler for loops: $build_jit Do internal array bounds checking: $BOUNDS_CHECKING Use octave_allocator: $USE_OCTAVE_ALLOCATOR Build static libraries: $STATIC_LIBS @@ -2512,9 +2582,7 @@ OCTAVE_CONFIGURE_WARNING_SUMMARY if $ENABLE_DYNAMIC_LINKING; then - if $SHARED_LIBS; then - true - else + if test $SHARED_LIBS = false; then AC_MSG_WARN([You used --enable-dl but not --enable-shared.]) AC_MSG_WARN([Are you sure that is what you want to do?]) warn_msg_printed=true @@ -2551,9 +2619,7 @@ warn_msg_printed=true fi -if $native_graphics; then - true; -else +if test $native_graphics = false; then AC_MSG_WARN([]) AC_MSG_WARN([I didn't find the necessary libraries to compile native]) AC_MSG_WARN([graphics. It isn't necessary to have native graphics,])
--- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's doc/interpreter directory +# Makefile for Octave's doc directory # # Copyright (C) 1993-2012 John W. Eaton # @@ -20,8 +20,8 @@ include $(top_srcdir)/build-aux/common.mk -## Avoid making multiple subdirs in parallel which can lead -## to a confusing error message stream +## Avoid making multiple subdirs in parallel +## which can lead to a confusing error message stream. .NOTPARALLEL: EXTRA_DIST = \ @@ -29,5 +29,5 @@ texinfo.tex \ texmf.cnf -SUBDIRS = faq icons interpreter liboctave refcard +SUBDIRS = icons interpreter liboctave refcard
deleted file mode 100644 --- a/doc/faq/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile for octave's doc/faq directory -# -# Copyright (C) 1996-2012 John W. Eaton -# -# This file is part of Octave. -# -# Octave 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. -# -# Octave 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 Octave; see the file COPYING. If not, see -# <http://www.gnu.org/licenses/>. - -include $(top_srcdir)/build-aux/common.mk - -## Automake generated rules for documentation are not parallel-safe. -## Restrict current directory to run serially -.NOTPARALLEL: - -TEXINFO_TEX = ../texinfo.tex - -info_TEXINFOS = OctaveFAQ.texi - -all-local: dvi html pdf ps - -EXTRA_DIST = OctaveFAQ.dvi OctaveFAQ.html OctaveFAQ.pdf OctaveFAQ.ps -
deleted file mode 100644 --- a/doc/faq/OctaveFAQ.texi +++ /dev/null @@ -1,1314 +0,0 @@ -% Copyright (C) 1997-2012 John W. Eaton -% -% This file is part of Octave. -% -% Octave 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. -% -% Octave 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 Octave; see the file COPYING. If not, see -% <http://www.gnu.org/licenses/>. - -\input texinfo.tex @c -*-texinfo-*- - -@setfilename OctaveFAQ.info -@settitle Frequently asked questions about Octave (with answers) - -@setchapternewpage off -@direntry -* OctaveFAQ: (OctaveFAQ). Frequently asked questions about Octave -@end direntry -@titlepage -@title Octave FAQ -@subtitle Frequently asked questions about Octave -@subtitle @today{} -@sp 1 -@author John W. Eaton and David Bateman -@page -@end titlepage - -@ifnottex -@node Top -@top -@unnumbered Preface -@cindex FAQ for Octave, latest version -@end ifnottex - -This is a list of frequently asked questions (FAQ) for Octave users. - -We are always looking for new questions (@emph{with} answers), better -answers, or both. Please send suggestions to -@url{http://bugs.octave.org}. If you have general questions about -Octave, or need help for something that is not covered by the Octave -manual or the FAQ, please use the @email{help@@octave.org} mailing list. - -This FAQ is intended to supplement, not replace, the Octave manual. -Before posting a question to the @email{help@@octave.org} mailing list, -you should first check to see if the topic is covered in the manual. - -@menu -* What is Octave?:: -* Licensing Issues:: -* How can I cite Octave?:: -* Series 3.4.N:: -* Octave Features:: -* Learning more about Octave:: -* Getting Octave:: -* Installation:: -* Common problems:: -* Using Octave:: -* @sc{Matlab} compatibility:: -* Index:: -@end menu - -@node What is Octave? -@chapter What is Octave? - -Octave is a high-level interactive language, primarily intended for -numerical computations that is mostly compatible with -@sc{Matlab}.@footnote{@sc{Matlab} is a registered trademark of The -MathWorks, Inc.} - -Octave can do arithmetic for real, complex or integer-valued scalars -and matrices, solve sets of nonlinear algebraic equations, integrate -functions over finite and infinite intervals, and integrate systems of -ordinary differential and differential-algebraic equations. - -Octave uses the GNU readline library to handle reading and editing -input. By default, the line editing commands are similar to the -cursor movement commands used by GNU Emacs, and a vi-style line -editing interface is also available. At the end of each session, the -command history is saved, so that commands entered during previous -sessions are not lost. - -The Octave distribution includes a 650+ page Texinfo manual. Access to -the complete text of the manual is available via the @code{doc} command -at the Octave prompt. - -@menu -* Who develops Octave?:: -* Why GNU Octave?:: -* What version should I use?:: -* On what platforms does Octave run?:: -@end menu - -@node Who develops Octave? -@section Who develops Octave? - -Discussions about writing the software that would eventually become -Octave started in about 1988 with James B. Rawlings and John W. Eaton at -the University of Texas. John W. Eaton was the original author of -Octave, starting full-time development in February 1992. He is still the -primary maintainer. The community of users/developers has in addition -contributed some code and fuels the discussion on the mailing lists -@email{help@@octave.org} (user forum), @email{maintainers@@octave.org} -(development issues), and @email{octave-dev@@lists.sourceforge.net} (all -things related to the Octave Forge repository of user-contributed -functions). - -@node Why GNU Octave? -@section Why GNU Octave? - -The GNU Project was launched in 1984 to develop a complete Unix-like -operating system which is free software: the GNU system. - -GNU is a recursive acronym for ``GNU's Not Unix''; it is pronounced -guh-noo, approximately like canoe. - -The Free Software Foundation (FSF) is the principal organizational -sponsor of the GNU Project. - -Octave became GNU Octave in 1997 (beginning with version 2.0.6). This -meant agreeing to consider Octave a part of the GNU Project and support -the efforts of the FSF. However, Octave is not and has never been -developed by the FSF. - -For more information about the GNU project, see @url{www.gnu.org}. - -@cindex FSF [Free Software Foundation] -@cindex GNU [GNU's not unix] - -@node What version should I use? -@section What version should I use? - -In general, you will find the latest version on -@url{http://www.octave.org/download.html}. It is recommended to use the -``stable'' version of octave for general use, and the ``development'' -version if you want the latest features. - -A list of user-visible changes since the last release is available in -the file @file{NEWS}. The file @file{ChangeLog} in the source -distribution contains a more detailed record of changes made since the -last release. - -@node On what platforms does Octave run? -@section On what platforms does Octave run? - -Octave runs on various Unices---at least Linux and Solaris, Mac OS X, -Windows and anything you can compile it on. Binary distributions exist -at least for Debian, Suse, Fedora and RedHat Linuxes (Intel and AMD -@c Does Vista work? I get the feeling that even Windows users are trying -@c to forget Vista like a bad nightmare. Tatsuro only confirmed XP and -@c 7. I am tentatively assuming that Vista also works. -CPUs, at least), for Mac OS X and Windows' 98, 2000, XP, Vista, and 7. - -Two and three dimensional plotting is fully supported using gnuplot and -an experimental OpenGL backend. - -The underlying numerical solvers are currently standard Fortran ones -like LAPACK, LINPACK, ODEPACK, the BLAS, etc., packaged in a library -of C++ classes. If possible, the Fortran subroutines are compiled -with the system's Fortran compiler, and called directly from the C++ -functions. If that's not possible, you can still compile Octave if -you have the free Fortran to C translator f2c. - -Octave is also free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License, version 3, as -published by the Free Software Foundation, or at your option any later -version. - -@node Licensing Issues -@chapter Licensing Issues - -@menu -* If I write code using Octave do I have to release it under the GPL?: GPL -* Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave?: Licensing MEX Files -* I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL. Will you change the license of the Octave libraries for me?: Requesting License Changes -@end menu - -@node GPL -@section If I write code using Octave do I have to release it under the GPL? - -The answer depends on precisely how the code is written and how it works. - -Code written entirely in the scripting language of Octave -(interpreted code in .m files) may be released under the terms of -whatever license you choose. - -Code written using Octave's native plug-in interface (also known -as a .oct file) necessarily links with Octave internals and is -considered a derivative work of Octave and therefore must be -released under terms that are compatible with the GPL. - -Code written using Octave's implementation of the @sc{Matlab} MEX -interface may be released under the terms of whatever license you -choose, provided that the following conditions are met: - -@enumerate -@item -The plugin should not use any bindings that are specific to Octave. In -other words, the MEX file must use the MEX interface only, and not also -call on other Octave internals. It should be possible in principle to -use the MEX file with other programs that implement the MEX interface -(e.g., @sc{Matlab}). - -@item -The MEX file should not be distributed together with Octave in such a -way that they effectively create a single work. For example, you should -not distribute the MEX file and Octave together in a single package such -that Octave automatically loads and runs the MEX file when it starts up. -There are other possible ways that you might effectively create a single -work; this is just one example. -@end enumerate - -A program that embeds the Octave interpreter (e.g., by calling the -"octave_main" function), or that calls functions from Octave's -libraries (e.g., liboctinterp, liboctave, or libcruft) is -considered a derivative work of Octave and therefore must be -released under terms that are compatible with the GPL. - -@node Licensing MEX Files -@section Since the MEX interface allows plugins to be distributed under terms that are incompatible with the GPL, does this mean that you are encouraging people to to write non-free software for Octave? - -No. The original reason for implementing the MEX interface for Octave -was to allow Octave to run free software that uses MEX files (the -particular goal was to run SundialsTB in Octave). The intent was to -liberate that software from @sc{Matlab} and increase the amount of free -software available to Octave users, not to enable people to write -proprietary code for Octave. For the good of the community, we strongly -encourage users of Octave to release the code they write for Octave -under terms that are compatible with the GPL. - -@node Requesting License Changes -@section I wrote a program that links with Octave libraries and I don't want to release it under the terms of the GPL. Will you change the license of the Octave libraries for me? - -No. Instead of asking us to change the licensing terms for Octave, we -recommend that you release your program under terms that are compatible -with the GPL so that the free software community can benefit from your -work the same as you have benefited from the work of all the people who -have contributed to Octave. - -@node How can I cite Octave? -@chapter How can I cite Octave? - -Pointing to @url{http://www.octave.org} is good, because that gives -people a direct way to find out more. If citation of a URL is not -allowed by a publisher, or if you also want to point to a traditional -reference, then you can cite the Octave manual: - -@example -@group -@@BOOK@{eaton:2008, - author = "John W. Eaton and David Bateman and Søren Hauberg", - title = "GNU Octave Manual Version 3", - publisher = "Network Theory Limited", - year = "2008", - isbn = "0-9546120-6-X" -@} -@end group -@end example - -@node Series 3.4.N -@chapter What's new in version series 3.4.N and 3.5.N of Octave - -The 3.4.N series has enough new features to justify a minor version -number change. The full details are in the @file{NEWS} file, but in -brief 3.4.N series brings: - -@c This list is distilled from the NEWS file. Does it have enough -@c things? Does it have too many? -@itemize @bullet - -@item ARPACK now distributed with Octave - -@item Indexing optimisations - -@item FTP object using @file{libcurl} - -@item Better consistency with ismatrix, issquare, and issymetric - -@item Function handles aware of overloaded functions - -@item More efficient matrix division by making a single LAPACK call - -@item Other optimisations in matrix operations - -@item @code{bsxfun} optimised for basic arithmetic functions - -@item @sc{Matlab}-style ignoring of output arguments using @samp{~} - -@item Many optimisations of the @code{accumarray} function - -@item Sparse matrix indexing has been rewritten for speed - -@item Configuration pseudo-variables like @code{page_screen_output} -accept a ``local'' option argument to limit their scope to function -scope - -@item The @code{pkg} command now accepts a @code{-forge} option to pull -packages directly from Octave-forge - -@item Several @code{dlmread} improvements - -@item Octave now uses gnulib for better cross-platform compatibility - -@end itemize - -Here are some features that have been around since 3.2.N - -@itemize @bullet - -@item integer types - -@item fixed point arithmetic - -@item sparse matrices - -@item Linear programming code based on GLPK - -@item 64-bit compilation support - -@item gzipped files and stream and consequently support of @sc{Matlab} v7 files - -@item better support for both msvc and mingw - -@item a fully compatible MEX interface - -@item many many other minor features and compatibility changes - -@item OpenGL graphics toolkit - -An experimental OpenGL graphics toolkit to replace gnuplot. - -@item Object Orient Programming - -@item Block comments - -@item imwrite and imread - -The functions are based on the GraphicsMagick library. - -@item Lazy transpose - -Special treatment in the parser of things like "a' * b", where the -transpose is never explicitly formed but a flag is rather passed to the -underlying LAPACK code. - -@item Single precision type - -@item Improved array indexing -The underlying code used for indexing of arrays has been completely -rewritten and so the indexing of arrays is now significantly faster. - -@end itemize - -Here are some older features that have been around since 2.1.N: - -@itemize @bullet - -@item NDarrays - -@item cells - -@end itemize - -The 3.5.N series is the current development release and will become a -3.6.N release in the future. This series brings the following new -features: - -@itemize -@item Perl-compatible regular expressions are now part of Octave -@end itemize - - -@node Octave Features -@chapter What features are unique to Octave? - -@menu -* Functions defined on the command-line:: -* Comments with #:: -* Strings delimited by double quotes ":: -* Line continuation by backslash:: -* Informative block closing:: -* Coherent syntax:: -* Exclamation mark as not operator:: -* Increment and decrement operators:: -* Unwind-protect:: -* Built-in ODE and DAE solvers:: -@end menu - -This section refers to @sc{Matlab} R2010b and Octave 3.4.0. - -@node Functions defined on the command-line -@section Functions defined on the command-line - -Functions can be defined by entering code on the command line, a feature -not supported by @sc{Matlab}. For example, you may type: - -@example -@group -octave:1> function s = hello_string (to_who) -> ## Say hello -> if nargin<1, to_who = "World"; end -> s = ["Hello ",\ -> to_who]; -> endfunction -octave:2> hello_string ("Moon") -ans = Hello Moon -@end group -@end example - -@node Comments with # -@section Comments with # - -The pound character, @samp{#}, may be used to start comments, in -addition to @samp{%}. See the previous example. The major advantage of -this is that as @samp{#} is also a comment character for unix script -files, any file that starts with a string like @samp{#! /usr/bin/octave --q} will be treated as an octave script and be executed by octave. - -@node Strings delimited by double quotes " -@section Strings delimited by double quotes " -The double quote, @samp{"}, may be used to delimit strings, in addition -to the single quote @samp{'}. See the previous example. Also, -double-quoted strings include backslash interpretation (like C++, C, and -Perl) while single quoted are uninterpreted (like @sc{Matlab} and Perl). - -@node Line continuation by backslash -@section Line continuation by backslash - -Lines can be continued with a backslash, @samp{\}, in addition to three -points @samp{@dots{}}. See the previous example. - -@node Informative block closing -@section Informative block closing - -You may close @code{function}, @code{for}, @code{while}, @code{if}, -@dots{} blocks with @code{endfunction}, @code{endfor}, @code{endwhile}, -@dots{} keywords in addition to using @code{end}. As with @sc{Matlab}, the -@code{end} (or @code{endfunction}) keyword that marks the end of a -function defined in a @file{.m} file is optional. - -@node Coherent syntax -@section Coherent syntax - -Indexing other things than variables is possible, as in: -@example -@group -octave:1> [3 1 4 1 5 9](3) -ans = 4 -octave:2> cos ([0 pi pi/4 7])(3) -ans = 0.70711 -@end group -@end example - -@node Exclamation mark as not operator -@section Exclamation mark as not operator - -The exclamation mark @samp{!} (aka ``Bang!'') is a negation operator, just -like the tilde @samp{~}: - -@example -@group -octave:1> if ! strcmp (program_name, "octave"), -> "It's an error" -> else -> "It works!" -> end -ans = It works! -@end group -@end example - -@noindent -Note however that @sc{Matlab} uses the @samp{!} operator for shell -escapes, for which Octave requires using the @code{system} command. - -@node Increment and decrement operators -@section Increment and decrement operators - -@cindex Increment operators -@cindex Decrement operators -@cindex Operators, increment -@cindex Operators, decrement - -If you like the @samp{++}, @samp{+=} etc operators, rejoice! -Octave includes the C-like increment and decrement operators @samp{++} -and @samp{--} in both their prefix and postfix forms, in addition to -@samp{+=}, @samp{-=}, @samp{*=}, @samp{/=}, @samp{^=}, @samp{.*=}, -@samp{./=}, and @samp{.^=}. - -For example, to pre-increment the variable @var{x}, you would write -@code{++@var{x}}. This would add one to @var{x} and then return the new -value of @var{x} as the result of the expression. It is exactly the -same as the expression @code{@var{x} = @var{x} + 1}. - -To post-increment a variable @var{x}, you would write @code{x++}. -This adds one to the variable @var{x}, but returns the value that -@var{x} had prior to incrementing it. For example, if @var{x} is equal -to 2, the result of the expression @code{x++} is 2, and the new -value of @var{x} is 3. - -For matrix and vector arguments, the increment and decrement operators -work on each element of the operand. - -@node Unwind-protect -@section Unwind-protect - -@cindex Unwind-protect - -Octave supports a limited form of exception handling modeled after the -unwind-protect form of Lisp. The general form of an -@code{unwind_protect} block looks like this: - -@example -@group -unwind_protect - @var{body} -unwind_protect_cleanup - @var{cleanup} -end_unwind_protect -@end group -@end example - -@noindent -Where @var{body} and @var{cleanup} are both optional and may contain any -Octave expressions or commands. The statements in @var{cleanup} are -guaranteed to be executed regardless of how control exits @var{body}. - -The @code{unwind_protect} statement is often used to reliably restore -the values of global variables that need to be temporarily changed. - -@sc{Matlab} can be made to do something similar with their -@code{OnCleanUp} function that was introduced in 2008a. Octave also has -@code{onCleanup} since version 3.4.0. - -@node Built-in ODE and DAE solvers -@section Built-in ODE and DAE solvers - -@cindex DASSL -@cindex LSODE - -Octave includes LSODE and DASSL for solving systems of stiff ordinary -differential and differential-algebraic equations. These functions are -built in to the interpreter. - -@node Learning more about Octave -@chapter What documentation exists for Octave? - -@menu -* Documentation:: -* Getting additional help:: -* User community:: -* Bug reports:: -@end menu - -@node Documentation -@section What documentation exists for Octave? - -@cindex Octave, documentation - -The Octave distribution includes a 650+ page manual that is also -distributed under the terms of the GNU GPL. -It is available on the web at -@url{http://www.octave.org/docs.html} and you will also -find there instructions on how to order a paper version. - -The complete text of the Octave manual is also available using the GNU -Info system via the GNU Emacs, info, or xinfo programs, or by using -the @samp{doc} command to start the GNU info browser directly from -the Octave prompt. - -If you have problems using this documentation, or find that some topic -is not adequately explained, indexed, or cross-referenced, please report -it on @url{http://bugs.octave.org}. - -@node Getting additional help -@section Getting additional help - -@cindex Additional help -@cindex Mailing lists, help-octave - -If you can't find an answer to your question, the -@email{help@@octave.org} mailing list is available for questions related -to using, installing, and porting Octave that are not adequately -answered by the Octave manual or by this document. - -@node User community -@section User community - -To subscribe to the list, go to @url{http://www.octave.org/archive.html} -and follow the link to the subscription page for the list. - -@strong{Please do not} send requests to be added or removed from the -mailing list, or other administrative trivia to the list itself. - -An archive of old postings to the help-octave mailing list is maintained -on @url{http://www.octave.org/archive.html}. - -You will also find some user advice and code spread over the web. Good -starting points are the Octave Wiki @url{http://wiki.octave.org} and -Octave-Forge @url{http://octave.sourceforge.net} - -@node Bug reports -@section I think I have found a bug in Octave. - -@cindex Bug in Octave, newly found - -``I think I have found a bug in Octave, but I'm not sure. How do I know, -and who should I tell?'' - -@cindex Manual, for Octave - -First, see the section on bugs and bug reports in the Octave manual. -When you report a bug, make sure to describe the type of computer you -are using, the version of the operating system it is running, and the -version of Octave that you are using. Also provide enough code and -configuration details of your operating system so that the Octave -maintainers can duplicate your bug. - -@node Getting Octave -@chapter Getting Octave - -@menu -* Source code:: -* Pre-compiled binary packages:: -* Octave for other platforms:: -@end menu - -@node Source code -@section Source code -@cindex Source code - -Source code is available on the Octave development site, where you are -sure to get the latest version. - -@itemize @bullet -@item @url{http://www.octave.org/download.html} -@item @url{ftp://ftp.octave.org/pub/octave/} -@end itemize - -Since Octave is distributed under the terms of the GPL, you can get -Octave from a friend who has a copy, or from the Octave website. - -@node Pre-compiled binary packages -@section Pre-compiled binary packages -@cindex Pre-compiled binary packages -@cindex Binaries - -The Octave project does not distribute binary packages, but other -projects do. For an up-to-date listing of packagers, see: - -@itemize @bullet -@item @url{http://www.octave.org/download.html} -@item @url{http://wiki.octave.org/wiki.pl?CategoryInstall} -@end itemize - -As of today, Octave binaries are available at least on Debian, Ubuntu, -RedHat, Suse and Fedora GNU/Linuxen, Mac OS X, Windows' 98, 2000 and XP, -Vista, and 7. - -@node Octave for other platforms -@section How do I get a copy of Octave for (some other platform)? - -@cindex VMS support -@cindex VAX -@cindex MS-DOS support -@cindex Windows support -@cindex DJGPP -@cindex EMX -@cindex OS/2 support - -Octave currently runs on Unix-like systems, Mac OS X, and Windows. -It should be possible to make Octave work on other systems as well. -If you are interested in porting Octave to other systems, please contact -@email{maintainers@@octave.org}. - -@c @menu -@c * Octave for Unix:: -@c * Octave for other platforms:: -@c * latest versions:: -@c @end menu - -@c @cindex Octave, ordering -@c @cindex Octave, getting a copy - -@node Installation -@chapter Installation Issues and Problems - -@cindex Octave, building - -Octave 3.4 require approximately 1.3 GB of disk storage to unpack and -compile from source (considerably less if you don't compile with -debugging symbols). Once installed, Octave requires approximately 355 MB -of disk space (again, considerably less if you don't compile with -debugging symbols, approximately 50 MB). - -@menu -* What else do I need?:: -* Other C++ compilers?:: -@end menu - -@node What else do I need? -@section What else do I need? - -@cindex GNU gcc -@cindex GNU g++ -@cindex libg++ -@cindex GNU Make -@cindex Flex -@cindex GNU Bison - -To compile Octave, you will need a recent version of GNU Make. You -will also need GCC 4.3 or later, although GCC 4.4 or later is -recommended. - -@strong{You must have GNU Make to compile octave}. Octave's Makefiles -use features of GNU Make that are not present in other versions of make. -GNU Make is very portable and easy to install. - -@node Other C++ compilers? -@section Can I compile Octave with another C++ compiler? - -Yes, but development is done primarily with GCC, so you may hit some -incompatibilities. Octave is intended to be portable to any standard -conforming compiler. If you have difficulties that you think are bugs, -please report them to the @url{http://bugs.octave.org} bug tracker, or -ask for help on the @email{help@@octave.org} mailing list. - -@node Common problems -@chapter Common problems - -This list is probably far too short. Feel free to suggest additional -questions (preferably with answers!) - -@itemize @bullet -@item -Octave takes a long time to find symbols. - -Octave uses the @code{genpath} function to recursively add directories -to the list of directories searched for function files. Check the list -of directories with the @code{path} command. If the path list is very -long check your use of the @code{genpath} function. - -@item -When plotting Octave occasionally gives me errors like @samp{gnuplot> 9 -0.735604 line 26317: invalid command}. - -There is a known bug in gnuplot 4.2 that can cause an off by one error -while piping data to gnuplot. It has been fixed in gnuplot 4.4. - -If you have obtained your copy of Octave from a distribution please file -a bug report requesting that the fix reported in the above bug report be -included. - -@item -I cannot install a package. Octave complains about a missing -@code{mkoctfile}. - -Most distributions split Octave into several packages. The script -@code{mkoctfile} is then part of a separate package: -@itemize @minus -@item -Debian/Ubuntu - -@c This will work once we upload the Octave packages without a version -@c in their name to Debian. -@code{aptitude install octave-headers} - -@item -Fedora - -@code{yum install octave-devel} - -@end itemize -@end itemize - -@node Using Octave -@chapter Using Octave - -@menu -* How do I set the number of displayed decimals?:: -* How does Octave solve linear systems?:: -@end menu - -@cindex Tips and tricks -@cindex Using Octave - -@node How do I set the number of displayed decimals? -@section How do I set the number of displayed decimals? - -@example -@group -octave:1> format long -octave:2> pi -pi = 3.14159265358979 -octave:3> format short -octave:4> pi -pi = 3.1416 -@end group -@end example - -@node How does Octave solve linear systems? -@section How does Octave solve linear systems? - -@cindex backslash operator - -In addition to consulting Octave's source for the precise details, the -Octave manual contains a complete high-level description of the -algorithm that Octave uses to decide how to solve a particular linear -system, e.g. how the backslash operator @code{A\x} will be interpreted. -Sections ``Techniques Used for Linear Algebra'' and ``Linear Algebra on -Sparse Matrices'' from the manual describe this procedure. - -@node @sc{Matlab} compatibility -@chapter Porting programs from @sc{Matlab} to Octave - -@cindex @sc{Matlab} compatibility -@cindex Compatibility with @sc{Matlab} - -People often ask - -@quotation -I wrote some code for @sc{Matlab}, and I want to get it running under -Octave. Is there anything I should watch out for? -@end quotation - -@noindent -or alternatively - -@quotation -I wrote some code in Octave, and want to share it with @sc{Matlab} -users. Is there anything I should watch out for? -@end quotation - -@noindent -which is not quite the same thing. There are still a number of -differences between Octave and @sc{Matlab}, however in general -differences between the two are considered as bugs. Octave might -consider that the bug is in @sc{Matlab} and do nothing about it, but -generally functionality is almost identical. If you find a difference -between Octave behavior and @sc{Matlab}, then you should send a -description of this difference (with code illustrating the difference, -if possible) to @url{http://bugs.octave.org}. - -Furthermore, Octave adds a few syntactical extensions to @sc{Matlab} -that might cause some issues when exchanging files between @sc{Matlab} -and Octave users. As both Octave and @sc{Matlab} are under constant -development the information in this section is subject to change at -anytime. - -You should also look at the page -@url{http://octave.sourceforge.net/packages.html} and -@url{http://octave.sourceforge.net/doc/} that has a function reference -that is up to date. You can use this function reference to see the -number of octave function that are available and their @sc{Matlab} -compatibility. - -The major differences between Octave 3.4.N and @sc{Matlab} R2010b are: - -@itemize @bullet -@item Nested Functions - -Octave has limited support for nested functions. That is - -@example -@group -function y = foo (x) - y = bar (x) - function y = bar (x) - y = @dots{}; - end -end -@end group -@end example - -is equivalent to - -@example -@group -function y = foo (x) - y = bar (x) -end -function y = bar (x) - y = @dots{}; -end -@end group -@end example - -The main difference with @sc{Matlab} is a matter of scope. While nested -functions have access to the parent function's scope in @sc{Matlab}, no -such thing is available in Octave, due to how Octave essentially -``un-nests'' nested functions. - -The authors of Octave consider the nested function scoping rules of -@sc{Matlab} to be more problems than they are worth as they introduce -difficult to find bugs as inadvertently modifying a variable in a -nested function that is also used in the parent is particularly easy. - -@item Differences in core syntax -There a few core @sc{Matlab} syntaxes that are not accepted by Octave, -these being - -@itemize @bullet -@item -Some limitations on the use of function handles. The major difference is -related to nested function scoping rules (as above) and their use with -function handles. - -@item -Some limitations of variable argument lists on the LHS of an expression, -though the most common types are accepted. - -@item -@sc{Matlab} classdef object oriented programming is not yet supported, -though work is underway and when development more on to Octave 3.5 this -will be included in the development tree. -@end itemize - -@item Differences in core functions -A large number of the @sc{Matlab} core functions (ie those that are in -the core and not a toolbox) are implemented, and certainly all of the -commonly used ones. There are a few functions that aren't implemented, -usually to do with specific missing Octave functionality (GUI, DLL, -Java, ActiveX, DDE, web, and serial functions). Some of the core -functions have limitations that aren't in the @sc{Matlab} version. For -example the @code{sprandn} function can not force a particular condition -number for the matrix like @sc{Matlab} can. - -@item Just-In-Time compiler -@sc{Matlab} includes a "Just-In-Time" compiler. This compiler allows the -acceleration of for-loops in @sc{Matlab} to almost native performance -with certain restrictions. The JIT must know the return type of all -functions called in the loops and so you can't include user functions in -the loop of JIT optimized loops. Octave doesn't have a JIT and so to -some might seem slower than @sc{Matlab}. For this reason you must -vectorize your code as much as possible. The MathWorks themselves have a -good document discussing vectorization at -@c It would be nice if we had our own guide for this instead of relying -@c on Matlab documentation. -@url{http://www.mathworks.com/support/tech-notes/1100/1109.html}. - -@item Compiler -On a related point, there is no Octave compiler, and so you can't -convert your Octave code into a binary for additional speed or -distribution. There have been several aborted attempts at creating an -Octave compiler. Should the JIT compiler above ever be implemented, an -Octave compiler should be more feasible. -@c Should we mention here any of the efforts to create a compiler? There -@c used to be a dead link here to http://www.stud.tu-ilmenau.de/~rueckn/ - -@item Graphic Handles -Up to Octave 2.9.9 there was no support for graphic handles in Octave -itself. In the 3.2.N versions of Octave and beyond the support for -graphics handles is converging towards full compatibility. The -@code{patch} function is currently limited to 2-D patches, due to an -underlying limitation in gnuplot, but the experimental OpenGL backend is -starting to see an implementation of 3-D patches. - -@item GUI -There are no @sc{Matlab} compatible GUI functions. There are a number of -bindings from Octave to Tcl/Tk, VTK and Zenity included in the Octave -@c Is it too early to mention here the nascent fltk UI buttons? -Forge project (@url{http://octave.sourceforge.net}) for example that can -be used for a GUI, but these are not @sc{Matlab} compatible. Work on a -@sc{Matlab} compatible GUI is in an alpha stage in the JHandles package -@c Is Jhandles still usable? I thought Michael Goffioul had more or less -@c already disowned it. -(@url{http://octave.sourceforge.net/jhandles/index.html}). This might be -an issue if you intend to exchange Octave code with @sc{Matlab} users. - -@item Simulink -Octave itself includes no Simulink support. Typically the simulink -models lag research and are less flexible, so shouldn't really be used -in a research environment. However, some @sc{Matlab} users that try to -use Octave complain about this lack. There is a similar package to -simulink for the Octave and R projects available at -@c is this project in any state of usability? -@url{http://www.scicraft.org/} - -@item Mex-Files -Octave includes an API to the @sc{Matlab} MEX interface. However, as MEX -is an API to the internals of @sc{Matlab} and the internals of Octave -differ from @sc{Matlab}, there is necessarily a manipulation of the data -to convert from a MEX interface to the Octave equivalent. This is -notable for all complex matrices, where @sc{Matlab} stores complex -arrays as real and imaginary parts, whereas Octave respects the C99/C++ -standards of co-locating the real/imag parts in memory. Also due to the -way @sc{Matlab} allows access to the arrays passed through a pointer, -the MEX interface might require copies of arrays (even non complex -ones). - -@item Block comments -Block comments denoted by "%@{" and "%@}" markers are supported by -Octave with some limitations. The major limitation is that block -comments are not supported within [] or @{@}. - -@item Mat-File format -There are some differences in the mat v5 file format accepted by Octave. -@sc{Matlab} recently introduced the "-V7.3" save option which is an HDF5 -format which is particularly useful for 64-bit platforms where the -standard @sc{Matlab} format can not correctly save variables. Octave -accepts HDF5 files, but is not yet compatible with the "-v7.3" versions -produced by @sc{Matlab}. - -Although Octave can load inline function handles saved by @sc{Matlab}, -it can not yet save them. - -Finally, Some multi-byte Unicode characters aren't yet treated in -mat-files. - -@item Profiler -Octave doesn't have a profiler. Though there is a patch for a flat -profiler, that might become a real profiler sometime in the future. See -the thread - -@c Did this idea go anywhere? Should it be mentioned? -@url{http://octave.1599824.n4.nabble.com/Octave-profiler-td1641945.html#a1641947} - -for more details. - -@item Toolboxes -Octave is a community project and so the toolboxes that exist are -donated by those interested in them through the Octave Forge website -(@url{http://octave.sourceforge.net}). These might be lacking in certain -functionality relative to the @sc{Matlab} toolboxes, and might not -exactly duplicate the @sc{Matlab} functionality or interface. - -@item Short-circuit & and | operators -The @code{&} and @code{|} operators in @sc{Matlab} short-circuit when -included in an if statement and not otherwise. In Octave only the -@code{&&} and @code{||} short circuit. Note that this means that - -@example -@group - if (a | b) - @dots{} - end -@end group -@end example - -and - -@example -@group - t = a | b; - if t - @dots{} - end -@end group -@end example - -@noindent -are different in @sc{Matlab}. This is really a @sc{Matlab} bug, but -there is too much code out there that relies on this behaviour to change -it. Prefer the || and && operators in if statements if possible. If you -need to use code written for @sc{Matlab} that depends on this buggy -behaviour, you can enable it since Octave 3.4.0 with the following -command: - -@example -@group - do_braindead_shortcircuit_evaluation (1) -@end group -@end example - -Note that the difference with @sc{Matlab} is also significant when -either argument is a function with side effects or if the first argument -is a scalar and the second argument is an empty matrix. For example, -note the difference between - -@example -@group - t = 1 | []; ## results in [], so... - if (t) 1, end ## in if ([]), this is false. -@end group -@end example - -and - -@example - if (1 | []) 1, end ## short circuits so condition is true. -@end example - -Another case that is documented in the @sc{Matlab} manuals is that - -@example -@group - t = [1, 1] | [1, 2, 3]; ## error - if ([1, 1] | [1, 2, 3]) 1, end ## OK -@end group -@end example - -Also @sc{Matlab} requires the operands of && and || to be scalar values -but Octave does not (it just applies the rule that for an operand to be -considered true, every element of the object must be nonzero or -logically true). - -Finally, note the inconsistence of thinking of the condition of an if -statement as being equivalent to @code{all (X(:))} when @var{X} is a -matrix. This is true for all cases EXCEPT empty matrices: - -@example -@group - if ([0, 1]) == if (all ([0, 1])) ==> i.e., condition is false. - if ([1, 1]) == if (all ([1, 1])) ==> i.e., condition is true. -@end group -@end example - -However, - -@example - if ([]) != if (all ([])) -@end example - -because @code{samp ([]) == 1} because, despite the name, it is really -returning true if none of the elements of the matrix are zero, and since -there are no elements, well, none of them are zero. This is an example -of vacuous truth. But, somewhere along the line, someone decided that if -@code{([])} should be false. Mathworks probably thought it just looks -wrong to have @code{[]} be true in this context even if you can use -logical gymnastics to convince yourself that "all" the elements of a -matrix that doesn't actually have any elements are nonzero. Octave -however duplicates this behavior for if statements containing empty -matrices. - -@item Solvers for singular, under- and over-determined matrices - -@sc{Matlab}'s solvers as used by the operators mldivide (\) and mrdivide -(/), use a different approach than Octave's in the case of singular, -under-, or over-determined matrices. In the case of a singular matrix, -@sc{Matlab} returns the result given by the LU decomposition, even -though the underlying solver has flagged the result as erroneous. Octave -has made the choice of falling back to a minimum norm solution of -matrices that have been flagged as singular which arguably is a better -result for these cases. - -In the case of under- or over-determined matrices, Octave continues to -use a minimum norm solution, whereas @sc{Matlab} uses an approach that -is equivalent to - -@example -@group -function x = mldivide (A, b) - [Q, R, E] = qr (A); - x = [A \ b, E(:, 1:m) * (R(:, 1:m) \ (Q' * b))] -end -@end group -@end example - -@noindent -While this approach is certainly faster and uses less memory than -Octave's minimum norm approach, this approach seems to be inferior in -other ways. - -A numerical question arises: how big can the null space component -become, relative to the minimum-norm solution? Can it be nicely bounded, -or can it be arbitrarily big? Consider this example: -OctaveFAQ.texi -@example -@group -m = 10; -n = 10000; -A = ones (m, n) + 1e-6 * randn (m,n); -b = ones (m, 1) + 1e-6 * randn (m,1); -norm (A \ b) -@end group -@end example - -@noindent -while Octave's minimum-norm values are around 3e-2, @sc{Matlab}'s -results are 50-times larger. For another issue, try this code: - -@example -@group -m = 5; -n = 100; -j = floor (m * rand (1, n)) + 1; -b = ones (m, 1); -A = zeros (m, n); -A(sub2ind (size (A),j,1:n)) = 1; -x = A \ b; -[dummy,p] = sort (rand (1,n)); -y = A(:,p) \ b; -norm (x(p)-y) -@end group -@end example - -@noindent -It shows that unlike in Octave, mldivide in @sc{Matlab} is not invariant -with respect to column permutations. If there are multiple columns of -the same norm, permuting columns of the matrix gets you different -result than permuting the solution vector. This will surprise many -users. - -Since the mldivide (\) and mrdivide (/) operators are often part of a -more complex expression, where there is no room to react to warnings or -flags, it should prefer intelligence (robustness) to speed, and so the -Octave developers are firmly of the opinion that Octave's approach for -singular, under- and over-determined matrices is a better choice that -@sc{Matlab}'s - -@item Octave extensions -The extensions in Octave over @sc{Matlab} syntax are -very useful, but might cause issues when sharing with @sc{Matlab} users. -A list of the major extensions that should be avoided to be compatible -with @sc{Matlab} are - -@itemize @bullet -@item -Comments in octave can be marked with @samp{#}. This allows POSIX -systems to have the first line as @samp{#! octave -q} and mark the -script itself executable. @sc{Matlab} doesn't have this feature due to -the absence of comments starting with @samp{#}". - -@item -Code blocks like @code{if}, @code{for}, @code{while}, etc can be -terminated with block specific terminations like @code{endif}. -@sc{Matlab} doesn't have this and all blocks must be terminated with -@code{end}. - -@item -Octave has a lisp like @code{unwind_protect} block that allows blocks of -code that terminate in an error to ensure that the variables that are -touched are restored. You can do something similar with -@code{try}/@code{catch} combined with @samp{rethrow (lasterror ())} in -@sc{Matlab}, however rethrow and lasterror are only available in Octave -2.9.10 and later. @sc{Matlab} 2008a also introduced @code{OnCleanUp} -that is similar to @code{unwind_protect}, except that the object created -by this function has to be explicitly cleared in order for the cleanup -code to run. - -Note that using @code{try}/@code{catch} combined with @samp{rethrow -(lasterror ())} can not guarantee that global variables will be -correctly reset, as it won't catch user interrupts with Ctrl-C. For -example - -@example -@group - global a - a = 1; - try - _a = a; - a = 2 - while true - end - catch - fprintf ('caught interrupt\n'); - a = _a; - rethrow (lasterror()); - end -@end group -@end example - -@noindent -compared to - -@example -@group - global a - a = 1; - unwind_protect - _a = a; - a = 2 - while true - end - unwind_protect_cleanup - fprintf ('caught interrupt\n'); - a = _a; - end -@end group -@end example - -Typing Ctrl-C in the first case returns the user directly to the -prompt, and the variable "a" is not reset to the saved value. In the -second case the variable "a" is reset correctly. Therefore @sc{Matlab} -gives no safe way of temporarily changing global variables. - -@item -Indexing can be applied to all objects in Octave and not just a -variable. Therefore @code{sin(x)(1:10);} for example is perfectly valid -in Octave but not @sc{Matlab}. To do the same in @sc{Matlab} you must do -@code{y = sin (x); y = y([1:10]);} - -@item -Octave has the operators "++", "--", "-=", "+=", "*=", etc. As -@sc{Matlab} doesn't, if you are sharing code these should be avoided. - -@item -Character strings in Octave can be denoted with double or single -quotes. There is a subtle difference between the two in that escaped -characters like @code{\n} (newline), @code{\t} (tab), etc are -interpreted in double quoted strings but not single quoted strings. This -difference is important on Windows platforms where the "\" character is -used in path names, and so single quoted strings should be used in -paths. @sc{Matlab} doesn't have double quoted strings and so they should -be avoided if the code will be transferred to a @sc{Matlab} user. -@end itemize - -@end itemize - -@node Index -@appendix Concept Index - -@printindex cp - -@page -@contents -@bye
--- a/doc/icons/Makefile.am +++ b/doc/icons/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's doc/icons directory +# Makefile for Octave's doc/icons directory # # Copyright (C) 2012 John W. Eaton #
--- a/doc/interpreter/Makefile.am +++ b/doc/interpreter/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's doc/interpreter directory +# Makefile for Octave's doc/interpreter directory # # Copyright (C) 1993-2012 John W. Eaton # @@ -20,10 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -## Automake generated rules for documentation are not parallel-safe. -## Restrict current directory to run serially -## .NOTPARALLEL: - TEXINFO_TEX = ../texinfo.tex ## Leading PATH_SEPARATOR required due to weak parsing by dvips (12/04/09) @@ -91,8 +87,9 @@ $(IMAGES_EPS) \ $(IMAGES_PDF) \ $(IMAGES_PNG) \ - $(IMAGES_TXT) \ - $(HTMLDIR_IMAGES) + $(IMAGES_TXT) + +HTMLDIR_IMAGES = $(addprefix octave.html/, $(IMAGES_PNG)) LOGOS = \ octave_logo.eps \ @@ -153,32 +150,31 @@ TXI_SRC = $(MUNGED_TEXI_SRC:.texi=.txi) -info_TEXINFOS = octave.texi - -octave_TEXINFOS = \ +BUILT_TEXINFOS = \ contributors.texi \ $(MUNGED_TEXI_SRC) -octave.info octave.dvi octave.html/index.html octave.pdf: $(srcdir)/version.texi $(octave_TEXINFOS) $(EXAMPLE_FILES) $(srcdir)/images.mk - -octave.info: $(IMAGES_TXT) - -octave.dvi octave.ps: $(IMAGES_EPS) octave_logo.eps +info_TEXINFOS = octave.texi -octave.html/index.html: $(IMAGES_PNG) +octave_TEXINFOS = \ + $(BUILT_TEXINFOS) \ + $(EXAMPLE_FILES) \ + $(IMAGES) \ + $(LOGOS) \ + $(srcdir)/images.mk -octave.html: - if [ -d octave.html ]; then true; else mkdir octave.html; fi +all-local: dvi html pdf ps doc-cache -octave.pdf: $(IMAGES_PDF) octave_logo.pdf +html: $(HTMLDIR_IMAGES) + +$(HTMLDIR_IMAGES): $(IMAGES_PNG) | octave.html + cp $(@F) octave.html ## The texi2dvi script (used to create both PDF and DVI output formats) -## uses some fixed temporary file names, so wait for DVI file to be -## generated before creating PDF file to avoid conflicts. +## uses some fixed temporary file names. In order to avoid a race condition +## the DVI and PDF builds are forced to run serially through a Makefile rule. octave.pdf: octave.dvi -all-local: dvi html pdf ps doc-cache $(HTMLDIR_IMAGES) - # Prevent packaging of distribution unless all libraries # necessary to create documentation are present dist-hook: @@ -226,12 +222,12 @@ --no-validate --no-headers --no-split --output INSTALL $< mv INSTALL ../../INSTALL.OCTAVE + undocumented_list: rm -f $@ -$(PERL) $(srcdir)/doccheck/mk_undocumented_list > $@ .PHONY: undocumented_list - SPELLCHECK_FILES = $(MUNGED_TEXI_SRC:.texi=.scheck) %.scheck: %.texi @@ -253,6 +249,7 @@ EXTRA_DIST = \ config-images.sh \ contributors.in \ + doc-cache \ find-docstring-files.sh \ images \ images.awk \ @@ -270,7 +267,10 @@ $(LOGOS) \ $(TXI_SRC) -DISTCLEANFILES = $(octave_TEXINFOS) doc-cache +clean-local: + rm -rf t2d_cache + +DISTCLEANFILES = $(BUILT_TEXINFOS) doc-cache MAINTAINERCLEANFILES = $(IMAGES)
--- a/doc/interpreter/arith.txi +++ b/doc/interpreter/arith.txi @@ -118,6 +118,24 @@ example, @code{sin} expects an angle in radians while @code{sind} expects an angle in degrees. +Octave uses the C library trigonometric functions. It is expected that these +functions are defined by the ISO/IEC 9899 Standard. This Standard is available +at: @url{http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf}. +Section F.9.1 deals with the trigonometric functions. The behavior of most of +the functions is relatively straightforward. However, there are some +exceptions to the standard behavior. Many of the exceptions involve the +behavior for -0. The most complex case is atan2. Octave exactly implements +the behavior given in the Standard. Including +@tex +$atan2(\pm0, -0)$ returns $\pm \pi$. +@end tex +@ifnottex +@code{atan2(+- 0, 0)} returns @code{+- pi}. +@end ifnottex + +It should be noted that @sc{matlab} uses different definitions which apparently +do not distinguish -0. + @DOCSTRING(sin) @DOCSTRING(cos) @DOCSTRING(tan) @@ -244,6 +262,8 @@ @DOCSTRING(sign) +@DOCSTRING(signbit) + @node Special Functions @section Special Functions
--- a/doc/interpreter/basics.txi +++ b/doc/interpreter/basics.txi @@ -101,6 +101,10 @@ in the system or user startup files that set the built-in variable @w{@env{EXEC_PATH}}. +@item --force-gui +@cindex @code{--force-gui} +Force the graphical user interface (GUI) to start. + @item --help @itemx -h @itemx -? @@ -141,10 +145,19 @@ remote shell command or inside an Emacs shell buffer. For another way to run Octave within Emacs, see @ref{Emacs Octave Support}. +@item --jit-debug +@cindex @code{--jit-debug} +Enable JIT compiler debugging and tracing. + @item --line-editing @cindex @code{--line-editing} Force readline use for command-line editing. +@item --no-gui +@cindex @code{--no-gui} +Disable the graphical user interface (GUI) and use the command line +interface (CLI) instead. + @item --no-history @itemx -H @cindex @code{--no-history} @@ -160,6 +173,10 @@ Don't initialize the search path for function files to include default locations. +@item --no-jit-compiler +@cindex @code{--no-jit-compiler} +Disable the JIT compiler used for accelerating loops. + @item --no-line-editing @cindex @code{--no-line-editing} Disable command-line editing. @@ -168,6 +185,11 @@ @cindex @code{--no-site-file} Don't read the site-wide @file{octaverc} initialization files. +@item --no-window-system +@cindex @code{--no-window-system} +Disable use of a windowing system including graphics. This forces a +strictly terminal-only environment. + @item --norc @itemx -f @cindex @code{--norc} @@ -199,6 +221,10 @@ @cindex @code{-q} Don't print the usual greeting and version message at startup. +@item --texi-macros-file @var{filename} +@cindex @code{--texi-macros-file @var{filename}} +Specify the name of the file containing Texinfo macros for use by makeinfo. + @item --traditional @itemx --braindead @cindex @code{--traditional} @@ -353,8 +379,8 @@ @node Getting Help @section Commands for Getting Help -@cindex on-line help -@cindex help, on-line +@cindex online help +@cindex help, online The entire text of this manual is available from the Octave prompt via the command @kbd{doc}. In addition, the documentation for
--- a/doc/interpreter/contrib.txi +++ b/doc/interpreter/contrib.txi @@ -41,7 +41,7 @@ development of Octave core, i.e., code that goes to Octave directly. You may consider developing and publishing a package instead; a great place for this is the allied Octave-Forge project -(@url{http://octave.sf.net}). Note that the Octave project is +(@url{http://octave.sourceforge.net}). Note that the Octave project is inherently more conservative and follows narrower rules. @node Building the Development Sources @@ -68,7 +68,7 @@ Check out a copy of the Octave sources: @example -hg clone http://hg.savannah.gnu.org/hgweb/octave +hg clone http://www.octave.org/hg/octave @end example @item @@ -82,7 +82,7 @@ Generate the necessary configuration files: @example -./autogen.sh +./bootstrap @end example @item
--- a/doc/interpreter/contributors.in +++ b/doc/interpreter/contributors.in @@ -48,6 +48,7 @@ Bill Denney Fabian Deutsch Christos Dimitrakakis +Pantxo Diribarne Vivek Dogra David M. Doolin Carnë Draug @@ -97,6 +98,7 @@ Ryan Hinton Roman Hodek A. Scottedward Hodel +Júlio Hoffimann Richard Allan Holcombe Tom Holroyd David Hoover @@ -189,6 +191,7 @@ Peter O'Gorman Thorsten Ohl Arno Onken +Valentin Ortega-Clavero Luis F. Ortiz Scott Pakin Gabriele Pannocchia @@ -295,6 +298,3 @@ Michael Zeising Federico Zenith Alex Zvoleff -Valentin Ortega-Clavero -Jacob Dawid -Júlio Hoffimann
--- a/doc/interpreter/doccheck/aspell-octave.en.pws +++ b/doc/interpreter/doccheck/aspell-octave.en.pws @@ -338,7 +338,7 @@ geq gesdd gesvd -gfortan +gfortran Ghostscript Ghostscript's gif @@ -456,6 +456,7 @@ Jacobian Jacobians ji +JIT jpeg JPEG jpg @@ -493,10 +494,10 @@ LF lfloor li -libcruft libcurl liblapack liboctave +liboctinterp Libtool licensors lineanchors @@ -507,6 +508,7 @@ linkprop literalspacing Liu +LLVM LM lm loadpath @@ -700,6 +702,7 @@ poisspdf poissrnd polyderiv +polyeig polyfit polyval POSIX @@ -734,6 +737,7 @@ QQ qrupdate QRUPDATE +QScintilla quadcc quadgk quadl @@ -1029,6 +1033,7 @@ wblinv wblpdf wblrnd +WebKit Weibull Welch welch
--- a/doc/interpreter/errors.txi +++ b/doc/interpreter/errors.txi @@ -115,7 +115,7 @@ @print{} @print{} @print{} Additional help for built-in functions and operators is -@print{} available in the on-line version of the manual. Use the command +@print{} available in the online version of the manual. Use the command @print{} `doc <topic>' to search the manual index. @print{} @print{} Help and information about Octave is also available on the WWW @@ -296,7 +296,10 @@ If a warning has such an ID the user can enable and disable this warning as will be described in the next section. To assign an ID to a warning, simply call @code{warning} with two string arguments, where the first -is the identification string, and the second is the actual warning. +is the identification string, and the second is the actual warning. Note +that warning IDs are in the format "NAMESPACE:WARNING-NAME". The namespace +"Octave" is used for Octave's own warnings. Any other string is available +as a namespace for user's own warnings. @DOCSTRING(warning) @@ -315,7 +318,7 @@ @example @group -warning ("non-negative-variable", +warning ("example:non-negative-variable", "'a' must be non-negative. Setting 'a' to zero."); @end group @end example @@ -325,8 +328,8 @@ @example @group -warning ("off", "non-negative-variable"); -warning ("non-negative-variable", +warning ("off", "example:non-negative-variable"); +warning ("example:non-negative-variable", "'a' must be non-negative. Setting 'a' to zero."); @end group @end example
--- a/doc/interpreter/image.txi +++ b/doc/interpreter/image.txi @@ -117,6 +117,8 @@ an RGB color. The color map must be of class @code{double} with values between 0 and 1. +@DOCSTRING(iscolormap) + @DOCSTRING(gray2ind) @DOCSTRING(ind2gray)
--- a/doc/interpreter/images.awk +++ b/doc/interpreter/images.awk @@ -4,7 +4,6 @@ exts[3] = "png"; exts[4] = "txt"; printf ("IMAGES_SRC =\n"); - printf ("HTMLDIR_IMAGES =\n"); for (i = 1; i <= 4; i++) { printf ("IMAGES_%s =\n", toupper (exts[i])); } @@ -25,18 +24,7 @@ printf ("IMAGES_%s += $(%s_%s)\n", uext, ubasename, uext); - if (ext == "png") { - printf ("HTMLDIR_IMAGES += "); - for (j = 2; j <= NF; j++) - printf (" octave.html/%s.png", $j); - printf ("\n"); - } - for (j = 2; j <= NF; j++) { - if (ext == "png") { - printf ("octave.html/%s.png: %s.png octave.html\n", $j, $j); - printf ("\tcp $< $@\n"); - } printf ("%s.%s: %s\n", $j, ext, script); printf ("\t$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval \"%s ('%s', '%s');\"\n", basename, $j, ext);
--- a/doc/interpreter/install.txi +++ b/doc/interpreter/install.txi @@ -284,7 +284,7 @@ @item Qt GUI and utility libraries (@url{}). Qt is required for building the GUI. It is a large framework, but the only components required are the GUI, -core, Webkit, and network modules. +core, WebKit, and network modules. @item SuiteSparse Sparse matrix factorization library @@ -539,7 +539,7 @@ Octave and other binaries that people will want to run directly. @item @var{prefix}/lib/octave-@var{version} -Libraries like libcruft.a and liboctave.a. +Libraries like liboctave.a and liboctinterp.a. @item @var{prefix}/octave-@var{version}/include/octave Include files distributed with Octave. @@ -796,12 +796,12 @@ @end example You must ensure that all Fortran sources except those in the -@file{libcruft/ranlib} directory are compiled such that INTEGERS are -8-bytes wide. If you are using gfortan, the configure script should +@file{liboctave/cruft/ranlib} directory are compiled such that INTEGERS are +8-bytes wide. If you are using gfortran, the configure script should automatically set the Makefile variable @w{@env{F77_INTEGER_8_FLAG}} to @option{-fdefault-integer-8}. If you are using another compiler, you must set this variable yourself. You should NOT set this flag in -@env{FFLAGS}, otherwise the files in @file{libcruft/ranlib} will be +@env{FFLAGS}, otherwise the files in @file{liboctave/cruft/ranlib} will be miscompiled. @item Other dependencies @@ -976,7 +976,7 @@ @end example @noindent -when compiling the Fortran subroutines in the @file{libcruft} +when compiling the Fortran subroutines in the @file{liboctave/cruft} subdirectory, you should either upgrade your compiler or try compiling with optimization turned off.
--- a/doc/interpreter/intro.txi +++ b/doc/interpreter/intro.txi @@ -524,7 +524,7 @@ @example @group fieldnames ([1, 2; 3, 4]) -error: fieldnames: wrong type argument `matrix' +error: fieldnames: wrong type argument 'matrix' @end group @end example
--- a/doc/interpreter/io.txi +++ b/doc/interpreter/io.txi @@ -230,6 +230,11 @@ @DOCSTRING(textscan) +The @code{importdata} function has the ability to work with a wide +variety of data. + +@DOCSTRING(importdata) + @menu * Saving Data on Unexpected Exits:: @end menu @@ -408,7 +413,7 @@ @group pct = 37; filename = "foo.txt"; -printf ("Processed %d%% of `%s'.\nPlease be patient.\n", +printf ("Processed %d%% of '%s'.\nPlease be patient.\n", pct, filename); @end group @end example @@ -418,7 +423,7 @@ @example @group -Processed 37% of `foo.txt'. +Processed 37% of 'foo.txt'. Please be patient. @end group @end example @@ -698,7 +703,7 @@ The following flags can be used to modify the behavior: -@c Not @samp so we can have ` ' as an item. +@c Not @samp so we can have ' ' as an item. @table @asis @item @samp{-} Left-justify the result in the field. Normally the result is
--- a/doc/interpreter/mk_doc_cache.m +++ b/doc/interpreter/mk_doc_cache.m @@ -121,4 +121,5 @@ cache(:,k:end) = []; # delete unused pre-allocated entries +save_header_format_string (["# doc-cache created by Octave " OCTAVE_VERSION ", %a %b %d %H:%M:%S %Y %Z"]); save ("-text", output_file, "cache");
--- a/doc/interpreter/mkoctfile.1 +++ b/doc/interpreter/mkoctfile.1 @@ -104,19 +104,19 @@ CFLAGS LD_CXX CPICFLAG LD_STATIC_FLAG CPPFLAGS LFLAGS - CXX LIBCRUFT - CXXFLAGS LIBOCTAVE - CXXPICFLAG LIBOCTINTERP - DEPEND_EXTRA_SED_PATTERN LIBS - DEPEND_FLAGS OCTAVE_LIBS - DL_LD OCTAVE_LINK_DEPS - DL_LDFLAGS OCT_LINK_DEPS - EXEEXT RDYNAMIC_FLAG - F77 READLINE_LIBS - F77_INTEGER_8_FLAG SED - FFLAGS XTRA_CFLAGS - FFTW3_LDFLAGS XTRA_CXXFLAGS - FFTW3_LIBS + CXX LIBOCTAVE + CXXFLAGS LIBOCTINTERP + CXXPICFLAG LIBS + DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS + DEPEND_FLAGS OCTAVE_LINK_DEPS + DL_LD OCT_LINK_DEPS + DL_LDFLAGS RDYNAMIC_FLAG + EXEEXT READLINE_LIBS + F77 SED + F77_INTEGER_8_FLAG XTRA_CFLAGS + FFLAGS XTRA_CXXFLAGS + FFTW3_LDFLAGS + FFTW3_LIBS FFTW3F_LDFLAGS .Ve .RE
--- a/doc/interpreter/octave.1 +++ b/doc/interpreter/octave.1 @@ -25,7 +25,7 @@ .fi .. .\" -------------------------------------------------------------------- -.TH OCTAVE 1 "4 February 2011" "GNU Octave" +.TH OCTAVE 1 "19 October 2012" "GNU Octave" .SH NAME octave \- A high-level interactive language for numerical computations. .SH SYNOPSIS @@ -44,9 +44,9 @@ .SH DOCUMENTATION The primary documentation for Octave is written using Texinfo, the GNU documentation system, which allows the same source files to be used to -produce on-line and printed versions of the manual. +produce online and printed versions of the manual. .PP -You can read the on-line copy of the Octave documentation by issuing +You can read the online copy of the Octave documentation by issuing the following command from within \fBoctave\fP. .Vb
--- a/doc/interpreter/oop.txi +++ b/doc/interpreter/oop.txi @@ -495,6 +495,13 @@ @cindex transpose, complex-conjugate @cindex unary minus +@c Need at least one plaintext sentence here between the @node and @float +@c table below or the two will overlap due to a bug in Texinfo. +@c This is not our fault; this *is* a ridiculous kluge. +The following table shows, for each built-in numerical operation, the +corresponding function name to use when providing an overloaded method for a +user class. + @float Table,tab:overload_ops @opindex + @opindex -
--- a/doc/interpreter/package.txi +++ b/doc/interpreter/package.txi @@ -24,7 +24,7 @@ installation of extra packages. The `Octave-Forge' project is a community-maintained set of packages that can be downloaded and installed in Octave. At the time of writing the `Octave-Forge' project -can be found on-line at @uref{http://octave.sourceforge.net}, but +can be found online at @uref{http://octave.sourceforge.net}, but since the Internet is an ever-changing place this may not be true at the time of reading. Therefore it is recommended to see the Octave website for an updated reference. @@ -211,6 +211,7 @@ @item package/ONEWS This is an optional file describing old entries from the @file{NEWS} file. +@cindex PKG_ADD @anchor{doc-PKG_ADD} @item package/PKG_ADD An optional file that includes commands that are run when the package @@ -235,6 +236,8 @@ @xref{PKG_ADD and PKG_DEL Directives}, for details on @w{@code{PKG_ADD}} directives. +@cindex PKG_DEL +@anchor{doc-PKG_DEL} @item package/PKG_DEL An optional file that includes commands that are run when the package is removed from the users path. Note that @w{@code{PKG_DEL}} directives in
--- a/doc/liboctave/Makefile.am +++ b/doc/liboctave/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's doc/liboctave directory +# Makefile for Octave's doc/liboctave directory # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007 John W. Eaton @@ -21,10 +21,6 @@ include $(top_srcdir)/build-aux/common.mk -## Automake generated rules for documentation are not parallel-safe. -## Restrict current directory to run serially -.NOTPARALLEL: - TEXINFO_TEX = ../texinfo.tex info_TEXINFOS = liboctave.texi @@ -52,7 +48,13 @@ all-local: dvi html pdf ps -liboctave.info liboctave.dvi liboctave.html liboctave.pdf: $(srcdir)/version.texi +## The texi2dvi script (used to create both PDF and DVI output formats) +## uses some fixed temporary file names. In order to avoid a race condition +## the DVI and PDF builds are forced to run serially through a Makefile rule. +liboctave.pdf: liboctave.dvi EXTRA_DIST = liboctave.dvi liboctave.html liboctave.pdf liboctave.ps +clean-local: + rm -rf t2d_cache +
--- a/doc/refcard/Makefile.am +++ b/doc/refcard/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's doc/refcard directory +# Makefile for Octave's doc/refcard directory # # Copyright (C) 1996-2012 John W. Eaton #
--- a/etc/HACKING +++ b/etc/HACKING @@ -41,11 +41,11 @@ this package from the repository. For the record, you will find all the relevant information on downloading sources at: - http://www.gnu.org/software/octave/download.html + http://www.octave.org/download.html -After cloning Octave, you will need to run the autogen.sh script: +After cloning Octave, you will need to run the bootstrap script: - $ ./autogen.sh + $ ./bootstrap This script will examine the source tree and generate some Makefile fragments and then runs the bootstrap script. The bootstrap script comes @@ -70,10 +70,10 @@ corresponding Mercurial revision if you update the working directory to a past revision not too far in the past. -Additional options besides --gnulib-srcdir can be passed to autogen.sh and -they will be forwarded without modification to the bootstrap script. +Additional options besides --gnulib-srcdir can be passed to bootstrap and +they will be forwarded without modification to the gnulib bootstrap script. -Once the autogen.sh and bootstrap scripts complete successfully, you may +Once the bootstrap and bootstrap_gnulib scripts complete successfully, you may run $ ./configure @@ -115,44 +115,54 @@ libgnu -- gnulib sources that we use. The files here are copied here from the gnulib directory by the - build-aux/bootstrap script that is run by the - autogen.sh script. + build-aux/bootstrap_gnulib script that is run by the + bootstrap script. - libcruft -- various numerical libraries (mostly Fortran) - - amos bessel functions + liboctave -- C++ interfaces to the numerical libraries, Fortran + numerical libraries, various OS facilities, and utility + functions - blas-xtra wrappers for blas functions used in Octave + array the base Array, NDArray, Matrix, and Sparse classes - daspk large scale differential algebraic equation solver + cruft various numerical libraries (mostly Fortran) + + amos bessel functions - dasrt differential algebraic equation solver with root finding + blas-xtra wrappers for blas functions used in Octave - dassl differential-algebraic system solver + daspk large scale differential algebraic equation solver + + dasrt differential algebraic equation solver with root finding - fftpack subroutines for fast fourier transforms + dassl differential-algebraic system solver - lapack-xtra wrappers for lapack functions used in Octave + fftpack subroutines for fast fourier transforms + + lapack-xtra wrappers for lapack functions used in Octave - misc miscellaneous utilities + misc miscellaneous utilities - odepack ordinary differential equation solver + odepack ordinary differential equation solver - ordered-qz code for ordering eigenvalues for QZ factorization + ordered-qz code for ordering eigenvalues for QZ factorization - quadpack subroutines for numerical integration + quadpack subroutines for numerical integration + + ranlib random number generators - ranlib random number generators + slatec-err slatec error handling library - slatec-err slatec error handling library + slatec-fn various special function subroutines - slatec-fn various special function subroutines - + numeric C++ numerical algorithms and interfaces to the Fortran + algorithms - liboctave -- The C++ interfaces to the numerical libraries and - various OS facilities. + operators code for operators that act on base classes such as Array + system OS-related functions + + util utility and miscellaneous functions libinterp -- The interpreter itself plus lots of infrastructure around it. Octave's extensive octave_value class @@ -160,7 +170,7 @@ types is defined here. The built-in functions are also defined here. - octave-value the octave_value class hierarchy. These are the + octave-value The octave_value class hierarchy. These are the container classes that hold various Octave data types like struct numerical arrays, structure arrays, and cell arrays.
--- a/etc/PROJECTS +++ b/etc/PROJECTS @@ -3,7 +3,7 @@ A list of proposed projects is maintained at: - http://wiki.octave.org/wiki.pl?Projects + http://wiki.octave.org/Projects If you start working steadily on a project, please let maintainers@octave.org know. We might have information that could help
--- a/etc/README.MacOS +++ b/etc/README.MacOS @@ -31,7 +31,7 @@ the current development sources using mercurial can be found on Octave's web-site below. - http://www.gnu.org/software/octave/download.html + http://www.octave.org/download.html Building on MacOS can vary significantly between versions. These instructions document the procedure for MacOS 10.6.X. @@ -77,7 +77,7 @@ Instructions for building Octave are available on the web at the link below. - http://wiki.octave.org/wiki.pl?BuildFromSource + http://wiki.octave.org/Build_from_source In addition, those wishing to build on MacOS X (10.6.x) should read section 2.1 above. @@ -143,7 +143,7 @@ See the link below for additional details about optional dependencies. - http://wiki.octave.org/wiki.pl?BuildFromSource + http://wiki.octave.org/Build_from_source TODO - Modify the configure script to test for 64 bit vecLib bug. When the bug is present, apply the wrapper solution. @@ -270,8 +270,8 @@ After installing each of the dependencies, the sources are compiled by setting the proper environment variables and then following the standard build sequence. The following is an example set of variables for a 32-bit build -using gcc-4.2. When building from the sources obtained from the mercurial -archive, ./autogen.sh must be run prior to ./configure. +using gcc-4.2. When building from the sources obtained from the Mercurial +archive, ./bootstrap must be run prior to ./configure. export FINK_PREFIX="/sw" export PREFIX="/usr/local/bin" @@ -385,7 +385,7 @@ Octave may now be built from a local mercurial archive by typing the commands below (these assume gcc-4.4 is installed by macports). - ./autogen.sh + ./bootstrap export PREFIX=/opt/local export CC=/opt/local/bin/gcc-mp-4.4 export CXX=/opt/local/bin/g++-mp-4.4
--- a/etc/README.MinGW +++ b/etc/README.MinGW @@ -73,7 +73,7 @@ ---------------------- The source for testing snapshots can be downloaded from the official Octave - web site. http://www.gnu.org/software/octave/download.html + web site. http://www.octave.org/download.html The very latest development code is also available via anonymous access to a read-only Mercurial archive. The method of download is described on the web @@ -94,7 +94,7 @@ http://thread.gmane.org/gmane.comp.gnu.octave.bugs/12361/focus=12404 To build development sources from the Mercurial repository you must run - 'autogen.sh' (bootstrap) before running configure and make. This requires + bootstrap before running configure and make. This requires that automake and autoconf tools be installed.
--- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's examples directory +# Makefile for Octave's examples directory # # Copyright (C) 1996-2012 John W. Eaton #
--- a/examples/mysparse.c +++ b/examples/mysparse.c @@ -56,7 +56,7 @@ } else if (mxIsLogical (prhs[0])) { - bool *pbr, *pbr2; + mxLogical *pbr, *pbr2; mexPrintf ("Matrix is %d-by-%d logical", " sparse matrix", m, n); mexPrintf (" with %d elements\n", nz);
deleted file mode 100644 --- a/libcruft/link-deps.mk +++ /dev/null @@ -1,30 +0,0 @@ -## The following libraries may be needed to satisfy gnulib dependencies: -## -## $(COPYSIGN_LIBM) -## $(FLOOR_LIBM) -## $(GETHOSTNAME_LIB) -## $(LIBSOCKET) -## $(LIB_NANOSLEEP) -## $(LTLIBINTL) -## $(ROUNDF_LIBM) -## $(ROUND_LIBM) -## $(TRUNCF_LIBM) -## $(TRUNC_LIBM) - -LIBCRUFT_LINK_DEPS = \ - $(COPYSIGN_LIBM) \ - $(FLOOR_LIBM) \ - $(GETHOSTNAME_LIB) \ - $(LIBSOCKET) \ - $(LIB_NANOSLEEP) \ - $(LTLIBINTL) \ - $(ROUNDF_LIBM) \ - $(ROUND_LIBM) \ - $(TRUNCF_LIBM) \ - $(TRUNC_LIBM) \ - $(LAPACK_LIBS) \ - $(BLAS_LIBS) \ - $(FLIBS) \ - $(LIBS) - -LIBCRUFT_LINK_OPTS =
--- a/libgnu/Makefile.am +++ b/libgnu/Makefile.am @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl --lib=libgnu --source-base=libgnu --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl base64 c-strcase closedir copysign copysignf crypto/md5 fclose fcntl fflush filemode fnmatch fopen fseek ftell getcwd gethostname getopt-gnu gettimeofday glob isatty link lstat mkdir mkfifo mkostemp mkstemp mktime nanosleep nproc opendir pathmax progname readdir readlink rename rewinddir rmdir round roundf sigaction signal sigprocmask sleep stat stdint stdio strftime strptime symlink sys_stat sys_time sys_times time times tmpfile trunc truncf unistd unlink vasprintf +# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl --lib=libgnu --source-base=libgnu --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=gl base64 canonicalize chdir close closedir copysign copysignf crypto/md5 dup2 fclose fcntl fflush filemode float floor floorf fnmatch fopen fseek ftell getcwd gethostname getopt-gnu gettimeofday glob isatty link lstat malloc-gnu mkdir mkfifo mkostemp mktime nanosleep nproc open opendir pathmax progname putenv readdir readlink realloc-gnu rename rmdir round roundf select sigaction signal sigprocmask sleep stat stddef stdint stdio strerror strftime strptime symlink sys_stat sys_time sys_times time times tmpfile trunc truncf unistd unlink vasprintf AUTOMAKE_OPTIONS = 1.5 gnits @@ -51,6 +51,7 @@ libgnu_la_LDFLAGS += -no-undefined libgnu_la_LDFLAGS += $(COPYSIGNF_LIBM) libgnu_la_LDFLAGS += $(COPYSIGN_LIBM) +libgnu_la_LDFLAGS += $(FLOORF_LIBM) libgnu_la_LDFLAGS += $(FLOOR_LIBM) libgnu_la_LDFLAGS += $(GETHOSTNAME_LIB) libgnu_la_LDFLAGS += $(LIBSOCKET) @@ -96,6 +97,14 @@ ## end gnulib module alloca-opt +## begin gnulib module areadlink-with-size + +libgnu_la_SOURCES += areadlink-with-size.c + +EXTRA_DIST += areadlink.h + +## end gnulib module areadlink-with-size + ## begin gnulib module at-internal @@ -111,17 +120,25 @@ ## end gnulib module base64 +## begin gnulib module bitrotate + +libgnu_la_SOURCES += bitrotate.h + +## end gnulib module bitrotate + ## begin gnulib module c-ctype libgnu_la_SOURCES += c-ctype.h c-ctype.c ## end gnulib module c-ctype -## begin gnulib module c-strcase - -libgnu_la_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c - -## end gnulib module c-strcase +## begin gnulib module canonicalize + +libgnu_la_SOURCES += canonicalize.c + +EXTRA_DIST += canonicalize.h + +## end gnulib module canonicalize ## begin gnulib module canonicalize-lgpl @@ -294,6 +311,16 @@ ## end gnulib module dirfd +## begin gnulib module dirname + +libgnu_la_SOURCES += dirname.c basename.c + +EXTRA_DIST += stripslash.c + +EXTRA_libgnu_la_SOURCES += stripslash.c + +## end gnulib module dirname + ## begin gnulib module dirname-lgpl libgnu_la_SOURCES += dirname-lgpl.c basename-lgpl.c stripslash.c @@ -466,6 +493,14 @@ ## end gnulib module fflush +## begin gnulib module file-set + +libgnu_la_SOURCES += file-set.c + +EXTRA_DIST += file-set.h + +## end gnulib module file-set + ## begin gnulib module filemode libgnu_la_SOURCES += filemode.c @@ -529,6 +564,15 @@ ## end gnulib module floor +## begin gnulib module floorf + + +EXTRA_DIST += floor.c floorf.c + +EXTRA_libgnu_la_SOURCES += floor.c floorf.c + +## end gnulib module floorf + ## begin gnulib module fnmatch BUILT_SOURCES += $(FNMATCH_H) @@ -751,6 +795,28 @@ ## end gnulib module glob +## begin gnulib module hash + +libgnu_la_SOURCES += hash.c + +EXTRA_DIST += hash.h + +## end gnulib module hash + +## begin gnulib module hash-pjw + +libgnu_la_SOURCES += hash-pjw.h hash-pjw.c + +## end gnulib module hash-pjw + +## begin gnulib module hash-triple + +libgnu_la_SOURCES += hash-triple.c + +EXTRA_DIST += hash-triple.h + +## end gnulib module hash-triple + ## begin gnulib module intprops @@ -895,6 +961,15 @@ ## end gnulib module lstat +## begin gnulib module malloc-gnu + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_la_SOURCES += malloc.c + +## end gnulib module malloc-gnu + ## begin gnulib module malloc-posix @@ -1276,15 +1351,6 @@ ## end gnulib module mkostemp -## begin gnulib module mkstemp - - -EXTRA_DIST += mkstemp.c - -EXTRA_libgnu_la_SOURCES += mkstemp.c - -## end gnulib module mkstemp - ## begin gnulib module mktime @@ -1382,6 +1448,15 @@ ## end gnulib module progname +## begin gnulib module putenv + + +EXTRA_DIST += putenv.c + +EXTRA_libgnu_la_SOURCES += putenv.c + +## end gnulib module putenv + ## begin gnulib module raise @@ -1409,6 +1484,15 @@ ## end gnulib module readlink +## begin gnulib module realloc-gnu + + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_la_SOURCES += realloc.c + +## end gnulib module realloc-gnu + ## begin gnulib module realloc-posix @@ -1463,6 +1547,14 @@ ## end gnulib module roundf +## begin gnulib module same + +libgnu_la_SOURCES += same.c + +EXTRA_DIST += same.h + +## end gnulib module same + ## begin gnulib module same-inode @@ -2230,6 +2322,24 @@ ## end gnulib module strings +## begin gnulib module strndup + + +EXTRA_DIST += strndup.c + +EXTRA_libgnu_la_SOURCES += strndup.c + +## end gnulib module strndup + +## begin gnulib module strnlen + + +EXTRA_DIST += strnlen.c + +EXTRA_libgnu_la_SOURCES += strnlen.c + +## end gnulib module strnlen + ## begin gnulib module strnlen1 libgnu_la_SOURCES += strnlen1.h strnlen1.c @@ -2970,12 +3080,47 @@ ## end gnulib module wctype-h +## begin gnulib module xalloc + +libgnu_la_SOURCES += xmalloc.c + +EXTRA_DIST += xalloc.h + +## end gnulib module xalloc + +## begin gnulib module xalloc-die + +libgnu_la_SOURCES += xalloc-die.c + +## end gnulib module xalloc-die + +## begin gnulib module xalloc-oversized + + +EXTRA_DIST += xalloc-oversized.h + +## end gnulib module xalloc-oversized + +## begin gnulib module xgetcwd + +libgnu_la_SOURCES += xgetcwd.c + +EXTRA_DIST += xgetcwd.h + +## end gnulib module xgetcwd + ## begin gnulib module xsize libgnu_la_SOURCES += xsize.h ## end gnulib module xsize +## begin gnulib module xstrndup + +libgnu_la_SOURCES += xstrndup.h xstrndup.c + +## end gnulib module xstrndup + mostlyclean-local: mostlyclean-generic @for dir in '' $(MOSTLYCLEANDIRS); do \
--- a/libgui/Makefile.am +++ b/libgui/Makefile.am @@ -1,3 +1,5 @@ +# Makefile for Octave's libgui directory +# # Copyright (C) 2012 John W. Eaton # # This file is part of Octave. @@ -18,8 +20,70 @@ include $(top_srcdir)/build-aux/common.mk -SUBDIRS = src +AUTOMAKE_OPTIONS = subdir-objects + +QT_INCDIR = @QT_INCDIR@ + +QT_LIBDIR = @QT_LIBDIR@ + +QT_LIBS = -lQtCore -lQtGui -lQtNetwork -lqscintilla2 + +QT_LDFLAGS = -L$(QT_LIBDIR) + +MOC_CPPFLAGS = + +octlib_LTLIBRARIES = liboctgui.la + +EXTRA_DIST = default-qt-settings + +CLEANFILES = + +BUILT_SOURCES = + +noinst_HEADERS = + +noinst_LTLIBRARIES = + +include src/module.mk +include qterminal-module.mk + +## liboctgui merely collects a bunch of compiled convenience libraries. +## It has no source code itself. +liboctgui_la_SOURCES = + +include link-deps.mk + +# Dummy C++ source to force C++ linking. +nodist_EXTRA_liboctgui_la_SOURCES = dummy.cc + +liboctgui_la_LIBADD = \ + qterminal/libqterminal.la \ + src/libgui-src.la \ + $(top_builddir)/libinterp/liboctinterp.la \ + $(top_builddir)/liboctave/liboctave.la \ + $(LIBOCTGUI_LINK_DEPS) + +# Increment these as needed and according to the rules in the libtool manual: +liboctgui_current = 0 +liboctgui_revision = 0 +liboctgui_age = 0 + +liboctgui_version_info = $(liboctgui_current):$(liboctgui_revision):$(liboctgui_age) + +liboctgui_la_LDFLAGS = \ + -version-info $(liboctgui_version_info) \ + $(NO_UNDEFINED_LDFLAG) \ + -bindir $(bindir) \ + $(LIBOCTGUI_LINK_OPTS) octetc_DATA = default-qt-settings -EXTRA_DIST = default-qt-settings +moc-%.cc: %.h + @MOC@ -o$@ $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(MOC_CPPFLAGS) $(liboctgui_la_CPPFLAGS) $< + +ui-%.h: %.ui + @UIC@ -o $@ $< + +qrc-%.cc: %.qrc + @RCC@ -o $@ $< +
new file mode 100644 --- /dev/null +++ b/libgui/qterminal-module.mk @@ -0,0 +1,94 @@ +EXTRA_DIST += \ + qterminal-module.mk + +noinst_HEADERS += \ + qterminal/libqterminal/QTerminal.h \ + qterminal/libqterminal/QTerminalInterface.h \ + qterminal/libqterminal/win32/QTerminalColors.h \ + qterminal/libqterminal/win32/QWinTerminalImpl.h \ + qterminal/libqterminal/unix/BlockArray.h \ + qterminal/libqterminal/unix/Character.h \ + qterminal/libqterminal/unix/CharacterColor.h \ + qterminal/libqterminal/unix/Emulation.h \ + qterminal/libqterminal/unix/ExtendedDefaultTranslator.h \ + qterminal/libqterminal/unix/Filter.h \ + qterminal/libqterminal/unix/History.h \ + qterminal/libqterminal/unix/KeyboardTranslator.h \ + qterminal/libqterminal/unix/konsole_wcwidth.h \ + qterminal/libqterminal/unix/kpty.h \ + qterminal/libqterminal/unix/kpty_p.h \ + qterminal/libqterminal/unix/LineFont.h \ + qterminal/libqterminal/unix/QUnixTerminalImpl.h \ + qterminal/libqterminal/unix/Screen.h \ + qterminal/libqterminal/unix/ScreenWindow.h \ + qterminal/libqterminal/unix/TerminalCharacterDecoder.h \ + qterminal/libqterminal/unix/Vt102Emulation.h \ + qterminal/libqterminal/unix/SelfListener.h \ + qterminal/libqterminal/unix/TerminalModel.h \ + qterminal/libqterminal/unix/TerminalView.h + +qterminal_libqterminal_la_MOC = \ + qterminal/libqterminal/moc-QTerminal.cc \ + qterminal/libqterminal/moc-QTerminalInterface.cc + +nodist_qterminal_libqterminal_la_SOURCES = $(qterminal_libqterminal_la_MOC) + +qterminal_libqterminal_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(QT_INCDIR) \ + -I$(QT_INCDIR)/QtCore \ + -I$(QT_INCDIR)/QtGui \ + -I$(srcdir)/qterminal/libqterminal + +qterminal_libqterminal_la_CFLAGS = $(AM_CFLAGS) + +qterminal_libqterminal_la_CXXFLAGS = $(AM_CXXFLAGS) + +if WIN32_TERMINAL + +qterminal_libqterminal_la_SOURCES = \ + qterminal/libqterminal/win32/QTerminalColors.cpp \ + qterminal/libqterminal/win32/QWinTerminalImpl.cpp + +qterminal_libqterminal_la_MOC += \ + qterminal/libqterminal/win32/moc-QWinTerminalImpl.cc + +qterminal_libqterminal_la_CPPFLAGS += -DUNICODE + +# This flag is required to let MOC know about Q_OS_WIN32. +MOC_CPPFLAGS += -DWIN32 + +else + +qterminal_libqterminal_la_SOURCES = \ + qterminal/libqterminal/unix/BlockArray.cpp \ + qterminal/libqterminal/unix/Emulation.cpp \ + qterminal/libqterminal/unix/Filter.cpp \ + qterminal/libqterminal/unix/History.cpp \ + qterminal/libqterminal/unix/KeyboardTranslator.cpp \ + qterminal/libqterminal/unix/konsole_wcwidth.cpp \ + qterminal/libqterminal/unix/kpty.cpp \ + qterminal/libqterminal/unix/QUnixTerminalImpl.cpp \ + qterminal/libqterminal/unix/Screen.cpp \ + qterminal/libqterminal/unix/ScreenWindow.cpp \ + qterminal/libqterminal/unix/TerminalCharacterDecoder.cpp \ + qterminal/libqterminal/unix/Vt102Emulation.cpp \ + qterminal/libqterminal/unix/SelfListener.cpp \ + qterminal/libqterminal/unix/TerminalModel.cpp \ + qterminal/libqterminal/unix/TerminalView.cpp + +qterminal_libqterminal_la_MOC += \ + qterminal/libqterminal/unix/moc-Emulation.cc \ + qterminal/libqterminal/unix/moc-Filter.cc \ + qterminal/libqterminal/unix/moc-QUnixTerminalImpl.cc \ + qterminal/libqterminal/unix/moc-ScreenWindow.cc \ + qterminal/libqterminal/unix/moc-SelfListener.cc \ + qterminal/libqterminal/unix/moc-TerminalModel.cc \ + qterminal/libqterminal/unix/moc-TerminalView.cc \ + qterminal/libqterminal/unix/moc-Vt102Emulation.cc + +endif + +noinst_LTLIBRARIES += qterminal/libqterminal.la + +CLEANFILES += $(qterminal_libqterminal_la_MOC)
deleted file mode 100644 --- a/libgui/src/Makefile.am +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (C) 2012 John W. Eaton -# -# This file is part of Octave. -# -# Octave 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. -# -# Octave 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 Octave; see the file COPYING. If not, see -# <http://www.gnu.org/licenses/>. - -include $(top_srcdir)/build-aux/common.mk - -QT_INCDIR = @QT_INCDIR@ - -QT_LIBDIR = @QT_LIBDIR@ - -QT_LIBS = -lQtCore -lQtGui -lQtNetwork -lqscintilla2 - -QT_LDFLAGS = -L$(QT_LIBDIR) - -SRCDIRS = \ - m-editor \ - qtinfo \ - octave-adapter \ - ../qterminal/libqterminal/unix \ - ../qterminal/libqterminal/win32 \ - ../qterminal/libqterminal \ - ../qterminal - -octave_gui_MOC = \ - m-editor/moc-file-editor-interface.cc \ - m-editor/moc-file-editor-tab.cc \ - m-editor/moc-file-editor.cc \ - m-editor/moc-find-dialog.cc \ - m-editor/moc-lexer-octave-gui.cc \ - moc-documentation-dockwidget.cc \ - moc-files-dockwidget.cc \ - moc-history-dockwidget.cc \ - moc-main-window.cc \ - moc-octave-qt-event-listener.cc \ - moc-settings-dialog.cc \ - moc-terminal-dockwidget.cc \ - moc-welcome-wizard.cc \ - moc-workspace-model.cc \ - moc-workspace-view.cc \ - octave-adapter/moc-octave-main-thread.cc \ - qtinfo/moc-parser.cc \ - qtinfo/moc-webinfo.cc - -octave_gui_UI = \ - settings-dialog.ui \ - welcome-wizard.ui - -octave_gui_UI_H = $(patsubst %.ui, ui-%.h, $(octave_gui_UI)) - -octave_gui_RC = qrc-resource.cc - -octlib_LTLIBRARIES = liboctgui.la - -liboctgui_la_SOURCES = \ - documentation-dockwidget.cc \ - files-dockwidget.cc \ - history-dockwidget.cc \ - m-editor/file-editor-tab.cc \ - m-editor/file-editor.cc \ - m-editor/find-dialog.cc \ - m-editor/lexer-octave-gui.cc \ - main-window.cc \ - octave-adapter/octave-event.cc \ - octave-adapter/octave-link.cc \ - octave-adapter/octave-main-thread.cc \ - octave-gui.cc \ - octave-qt-event-listener.cc \ - qtinfo/parser.cc \ - qtinfo/webinfo.cc \ - resource-manager.cc \ - settings-dialog.cc \ - symbol-information.cc \ - terminal-dockwidget.cc \ - welcome-wizard.cc \ - workspace-model.cc \ - workspace-view.cc - -nodist_liboctgui_la_SOURCES = $(octave_gui_MOC) $(octave_gui_RC) - -liboctgui_la_CPPFLAGS = \ - -I$(QT_INCDIR) \ - -I$(QT_INCDIR)/QtCore \ - -I$(QT_INCDIR)/QtGui \ - -I$(QT_INCDIR)/QtNetwork \ - -I$(srcdir)/../qterminal/libqterminal \ - -I$(srcdir)/m-editor \ - -I$(srcdir)/octave-adapter \ - -I$(srcdir)/qtinfo \ - -I$(srcdir)/../../libcruft/misc \ - -I../../liboctave \ - -I$(srcdir)/../../liboctave \ - -I../../libinterp \ - -I../../libinterp/interp-core \ - -I../../libinterp/interpfcn \ - -I../../libinterp/parse-tree \ - -I$(srcdir)/../../libinterp \ - -I$(srcdir)/../../libinterp/interp-core \ - -I$(srcdir)/../../libinterp/interpfcn \ - -I$(srcdir)/../../libinterp/octave-value \ - -I$(srcdir)/../../libtinerp/operators \ - -I$(srcdir)/../../libinterp/parse-tree - -include link-deps.mk - -liboctgui_la_LIBADD = \ - libqterminal.la \ - ../../libinterp/liboctinterp.la \ - ../../liboctave/liboctave.la \ - ../../libcruft/libcruft.la \ - $(LIBOCTGUI_LINK_DEPS) - -# Increment these as needed and according to the rules in the libtool manual: -liboctgui_current = 0 -liboctgui_revision = 0 -liboctgui_age = 0 - -liboctgui_version_info = $(liboctgui_current):$(liboctgui_revision):$(liboctgui_age) - -liboctgui_la_LDFLAGS = \ - -version-info $(liboctgui_version_info) \ - $(NO_UNDEFINED_LDFLAG) \ - -bindir $(bindir) \ - $(LIBOCTGUI_LINK_OPTS) - -noinst_HEADERS = \ - documentation-dockwidget.h \ - files-dockwidget.h \ - history-dockwidget.h \ - m-editor/file-editor-interface.h \ - m-editor/file-editor-tab.h \ - m-editor/file-editor.h \ - m-editor/find-dialog.h \ - m-editor/lexer-octave-gui.h \ - main-window.h \ - octave-adapter/octave-event-listener.h \ - octave-adapter/octave-event-observer.h \ - octave-adapter/octave-event.h \ - octave-adapter/octave-link.h \ - octave-adapter/octave-main-thread.h \ - octave-gui.h \ - octave-qt-event-listener.h \ - qtinfo/parser.h \ - qtinfo/webinfo.h \ - resource-manager.h \ - settings-dialog.h \ - symbol-information.h \ - terminal-dockwidget.h \ - welcome-wizard.h \ - workspace-model.h \ - workspace-view.h - -CLEANFILES = $(octave_gui_MOC) $(octave_gui_UI_H) $(octave_gui_RC) - -clean-local: - -if test "$(srcdir)" != "."; then \ - for d in $(SRCDIRS); do test -d $$d && rmdir $$d; done \ - fi - -BUILT_SOURCES = $(octave_gui_UI_H) - -octave_gui_ICONS = \ - icons/arrow_right.png \ - icons/artsbuilderexecute.png \ - icons/bookmark.png \ - icons/bp_next.png \ - icons/bp_prev.png \ - icons/bp_rm_all.png \ - icons/bp_toggle.png \ - icons/chat.png \ - icons/configure.png \ - icons/db_cont.png \ - icons/db_step_in.png \ - icons/db_step_out.png \ - icons/db_step.png \ - icons/db_stop.png \ - icons/editcopy.png \ - icons/editcut.png \ - icons/editpaste.png \ - icons/filenew.png \ - icons/fileopen.png \ - icons/filesaveas.png \ - icons/filesave.png \ - icons/find.png \ - icons/help_index.png \ - icons/icons_license \ - icons/jabber_protocol.png \ - icons/logo.png \ - icons/question.png \ - icons/redled.png \ - icons/redo.png \ - icons/search.png \ - icons/star.png \ - icons/stop.png \ - icons/terminal.png \ - icons/undo.png \ - icons/up.png \ - icons/zoom-in.png \ - icons/zoom-out.png - -EXTRA_DIST = \ - $(octave_gui_UI) \ - $(octave_gui_ICONS) \ - resource.qrc - -noinst_LTLIBRARIES = libqterminal.la - -noinst_HEADERS += \ - ../qterminal/libqterminal/QTerminal.h \ - ../qterminal/libqterminal/QTerminalInterface.h \ - ../qterminal/libqterminal/win32/QTerminalColors.h \ - ../qterminal/libqterminal/win32/QWinTerminalImpl.h \ - ../qterminal/libqterminal/unix/BlockArray.h \ - ../qterminal/libqterminal/unix/Character.h \ - ../qterminal/libqterminal/unix/CharacterColor.h \ - ../qterminal/libqterminal/unix/Emulation.h \ - ../qterminal/libqterminal/unix/ExtendedDefaultTranslator.h \ - ../qterminal/libqterminal/unix/Filter.h \ - ../qterminal/libqterminal/unix/History.h \ - ../qterminal/libqterminal/unix/KeyboardTranslator.h \ - ../qterminal/libqterminal/unix/konsole_wcwidth.h \ - ../qterminal/libqterminal/unix/kpty.h \ - ../qterminal/libqterminal/unix/kpty_p.h \ - ../qterminal/libqterminal/unix/LineFont.h \ - ../qterminal/libqterminal/unix/QUnixTerminalImpl.h \ - ../qterminal/libqterminal/unix/Screen.h \ - ../qterminal/libqterminal/unix/ScreenWindow.h \ - ../qterminal/libqterminal/unix/TerminalCharacterDecoder.h \ - ../qterminal/libqterminal/unix/Vt102Emulation.h \ - ../qterminal/libqterminal/unix/SelfListener.h \ - ../qterminal/libqterminal/unix/TerminalModel.h \ - ../qterminal/libqterminal/unix/TerminalView.h - -libqterminal_la_CPPFLAGS = \ - -I$(QT_INCDIR) \ - -I$(QT_INCDIR)/QtCore \ - -I$(QT_INCDIR)/QtGui \ - -I$(srcdir)/../qterminal/libqterminal - -libqterminal_la_MOC = \ - ../qterminal/libqterminal/moc-QTerminal.cc \ - ../qterminal/libqterminal/moc-QTerminalInterface.cc - -nodist_libqterminal_la_SOURCES = $(libqterminal_la_MOC) - -if WIN32_TERMINAL - -libqterminal_la_SOURCES = \ - ../qterminal/libqterminal/win32/QTerminalColors.cpp \ - ../qterminal/libqterminal/win32/QWinTerminalImpl.cpp - -libqterminal_la_MOC += ../qterminal/libqterminal/win32/moc-QWinTerminalImpl.cc - -else - -libqterminal_la_SOURCES = \ - ../qterminal/libqterminal/unix/BlockArray.cpp \ - ../qterminal/libqterminal/unix/Emulation.cpp \ - ../qterminal/libqterminal/unix/Filter.cpp \ - ../qterminal/libqterminal/unix/History.cpp \ - ../qterminal/libqterminal/unix/KeyboardTranslator.cpp \ - ../qterminal/libqterminal/unix/konsole_wcwidth.cpp \ - ../qterminal/libqterminal/unix/kpty.cpp \ - ../qterminal/libqterminal/unix/QUnixTerminalImpl.cpp \ - ../qterminal/libqterminal/unix/Screen.cpp \ - ../qterminal/libqterminal/unix/ScreenWindow.cpp \ - ../qterminal/libqterminal/unix/TerminalCharacterDecoder.cpp \ - ../qterminal/libqterminal/unix/Vt102Emulation.cpp \ - ../qterminal/libqterminal/unix/SelfListener.cpp \ - ../qterminal/libqterminal/unix/TerminalModel.cpp \ - ../qterminal/libqterminal/unix/TerminalView.cpp - -libqterminal_la_MOC += \ - ../qterminal/libqterminal/unix/moc-Emulation.cc \ - ../qterminal/libqterminal/unix/moc-Filter.cc \ - ../qterminal/libqterminal/unix/moc-QUnixTerminalImpl.cc \ - ../qterminal/libqterminal/unix/moc-ScreenWindow.cc \ - ../qterminal/libqterminal/unix/moc-SelfListener.cc \ - ../qterminal/libqterminal/unix/moc-TerminalModel.cc \ - ../qterminal/libqterminal/unix/moc-TerminalView.cc \ - ../qterminal/libqterminal/unix/moc-Vt102Emulation.cc - -endif - -moc-%.cc: %.h - test -d $(@D) || mkdir -p $(@D) - @MOC@ -o$@ $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboctgui_la_CPPFLAGS) $< - -ui-%.h: %.ui - @UIC@ -o $@ $< - -qrc-%.cc: %.qrc - @RCC@ -o $@ $< - -CLEANFILES += $(libqterminal_la_MOC)
--- a/libgui/src/documentation-dockwidget.cc +++ b/libgui/src/documentation-dockwidget.cc @@ -20,16 +20,23 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "documentation-dockwidget.h" -documentation_dock_widget::documentation_dock_widget (QWidget *parent) - : QDockWidget (parent) +documentation_dock_widget::documentation_dock_widget (QWidget *p) + : QDockWidget (p) { setObjectName ("DocumentationDockWidget"); + setWindowIcon (QIcon(":/actions/icons/logo.png")); setWindowTitle (tr ("Documentation")); connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); _webinfo = new webinfo (this); setWidget (_webinfo); @@ -43,8 +50,19 @@ } void -documentation_dock_widget::closeEvent (QCloseEvent *event) +documentation_dock_widget::closeEvent (QCloseEvent *e) { emit active_changed (false); - QDockWidget::closeEvent (event); + QDockWidget::closeEvent (e); } + +// slot for signal that is emitted when floating property changes +void +documentation_dock_widget::top_level_changed (bool floating) +{ + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlags hides it + } +}
--- a/libgui/src/documentation-dockwidget.h +++ b/libgui/src/documentation-dockwidget.h @@ -30,12 +30,14 @@ class documentation_dock_widget : public QDockWidget { Q_OBJECT -public: + public: documentation_dock_widget (QWidget *parent = 0); public slots: /** Slot to steer changing visibility from outside. */ void handle_visibility_changed (bool visible); + /** Slot when floating property changes */ + void top_level_changed (bool floating); signals: /** Custom signal that tells if a user has clicked away that dock widget. */
--- a/libgui/src/files-dockwidget.cc +++ b/libgui/src/files-dockwidget.cc @@ -20,6 +20,10 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "resource-manager.h" #include "files-dockwidget.h" @@ -29,11 +33,13 @@ #include <QSettings> #include <QProcess> #include <QDebug> +#include <QHeaderView> -files_dock_widget::files_dock_widget (QWidget *parent) - : QDockWidget (parent) +files_dock_widget::files_dock_widget (QWidget *p) + : QDockWidget (p) { setObjectName ("FilesDockWidget"); + setWindowIcon (QIcon(":/actions/icons/logo.png")); setWindowTitle (tr ("Current Directory")); setWidget (new QWidget (this)); @@ -77,20 +83,28 @@ _file_tree_view->setColumnHidden (3, true); _file_tree_view->setStatusTip (tr ("Doubleclick a file to open it.")); + // get sort column and order as well as cloumn state (order and width) + QSettings *settings = resource_manager::get_settings (); + // FIXME -- what should happen if settings is 0? + _file_tree_view->sortByColumn ( + settings->value ("filesdockwidget/sort_files_by_column",0).toInt (), + static_cast<Qt::SortOrder>(settings->value ("filesdockwidget/sort_files_by_order",Qt::AscendingOrder).toUInt ()) + ); + _file_tree_view->header ()->restoreState (settings->value ("filesdockwidget/column_state").toByteArray ()); + _current_directory->setText(_file_system_model->fileInfo (rootPathIndex). - absoluteFilePath ()); + absoluteFilePath ()); connect (_file_tree_view, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (item_double_clicked (const QModelIndex &))); // Layout the widgets vertically with the toolbar on top - QVBoxLayout * - layout = new QVBoxLayout (); - layout->setSpacing (0); - layout->addWidget (_navigation_tool_bar); - layout->addWidget (_file_tree_view); - layout->setMargin (1); - widget ()->setLayout (layout); + QVBoxLayout *vbox_layout = new QVBoxLayout (); + vbox_layout->setSpacing (0); + vbox_layout->addWidget (_navigation_tool_bar); + vbox_layout->addWidget (_file_tree_view); + vbox_layout->setMargin (1); + widget ()->setLayout (vbox_layout); // TODO: Add right-click contextual menus for copying, pasting, deleting files (and others) connect (_current_directory, SIGNAL (returnPressed ()), @@ -102,10 +116,22 @@ connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); setFocusProxy (_current_directory); } +files_dock_widget::~files_dock_widget () +{ + QSettings *settings = resource_manager::get_settings (); + int sort_column = _file_tree_view->header ()->sortIndicatorSection (); + Qt::SortOrder sort_order = _file_tree_view->header ()->sortIndicatorOrder (); + settings->setValue ("filesdockwidget/sort_files_by_column", sort_column); + settings->setValue ("filesdockwidget/sort_files_by_order", sort_order); + settings->setValue ("filesdockwidget/column_state", _file_tree_view->header ()->saveState ()); +} + void files_dock_widget::item_double_clicked (const QModelIndex & index) { @@ -115,7 +141,7 @@ } void -files_dock_widget::set_current_directory (QString currentDirectory) +files_dock_widget::set_current_directory (const QString& currentDirectory) { display_directory (currentDirectory); } @@ -135,7 +161,7 @@ } void -files_dock_widget::display_directory (QString directory) +files_dock_widget::display_directory (const QString& directory) { QFileInfo fileInfo (directory); if (fileInfo.exists ()) @@ -143,7 +169,7 @@ if (fileInfo.isDir ()) { _file_tree_view->setRootIndex (_file_system_model-> - index (fileInfo.absoluteFilePath ())); + index (fileInfo.absoluteFilePath ())); _file_system_model->setRootPath (fileInfo.absoluteFilePath ()); _current_directory->setText (fileInfo.absoluteFilePath ()); @@ -186,8 +212,19 @@ } void -files_dock_widget::closeEvent (QCloseEvent *event) +files_dock_widget::closeEvent (QCloseEvent *e) { emit active_changed (false); - QDockWidget::closeEvent (event); + QDockWidget::closeEvent (e); } + +// slot for signal that is emitted when floating property changes +void +files_dock_widget::top_level_changed (bool floating) +{ + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlags hides it + } +}
--- a/libgui/src/files-dockwidget.h +++ b/libgui/src/files-dockwidget.h @@ -39,15 +39,16 @@ #include <QLineEdit> /** - \class files_dock_widget - \brief Dock widget to display files in the current directory. - */ + \class files_dock_widget + \brief Dock widget to display files in the current directory. +*/ class files_dock_widget : public QDockWidget { Q_OBJECT -public: + public: /** Constructs a new files_dock_widget. */ files_dock_widget (QWidget *parent = 0); + ~files_dock_widget (); public slots: /** Slot for handling a change in directory via double click. */ @@ -57,12 +58,12 @@ void do_up_directory (); /** Sets the current directory being displayed. */ - void set_current_directory (QString currentDirectory); + void set_current_directory (const QString& currentDirectory); /** Accepts user input a the line edit for the current directory. */ void handle_directory_entered (); - void display_directory (QString directory); + void display_directory (const QString& directory); /** Tells the widget to react on changed settings. */ void notice_settings (); @@ -70,12 +71,15 @@ /** Slot to steer changing visibility from outside. */ void handle_visibility_changed (bool visible); + /** Slot when floating property changes */ + void top_level_changed (bool floating); + signals: /** Emitted, whenever the user requested to open a file. */ - void open_file (QString fileName); + void open_file (const QString& fileName); /** Emitted, whenever the currently displayed directory changed. */ - void displayed_directory_changed (QString directory); + void displayed_directory_changed (const QString& directory); /** Custom signal that tells if a user has clicke away that dock widget. */ void active_changed (bool active);
--- a/libgui/src/history-dockwidget.cc +++ b/libgui/src/history-dockwidget.cc @@ -24,54 +24,26 @@ #include <config.h> #endif +#include <QApplication> +#include <QClipboard> #include <QVBoxLayout> +#include <QMenu> + +#include "error.h" #include "cmd-hist.h" #include "history-dockwidget.h" +#include "octave-link.h" -history_dock_widget::history_dock_widget (QWidget * parent) - : QDockWidget (parent), octave_event_observer () +history_dock_widget::history_dock_widget (QWidget * p) + : QDockWidget (p) { setObjectName ("HistoryDockWidget"); construct (); } void -history_dock_widget::event_accepted (octave_event *e) -{ - if (dynamic_cast <octave_update_history_event*> (e)) - { - // Determine the client's (our) history length and the one of the server. - int clientHistoryLength = _history_model->rowCount (); - int serverHistoryLength = command_history::length (); - - // If were behind the server, iterate through all new entries and add - // them to our history. - if (clientHistoryLength < serverHistoryLength) - { - for (int i = clientHistoryLength; i < serverHistoryLength; i++) - { - _history_model->insertRow (0); - _history_model->setData (_history_model->index (0), - QString (command_history::get_entry (i).c_str ())); - } - } - } - - // Post a new update event in a given time. This prevents flooding the - // event queue. - _update_history_model_timer.start (); - delete e; -} - -void -history_dock_widget::event_reject (octave_event *e) -{ - delete e; -} - -void history_dock_widget::construct () { _history_model = new QStringListModel (); @@ -81,18 +53,23 @@ _history_list_view->setAlternatingRowColors (true); _history_list_view->setEditTriggers (QAbstractItemView::NoEditTriggers); _history_list_view->setStatusTip (tr ("Doubleclick a command to transfer it to the terminal.")); + _history_list_view->setSelectionMode (QAbstractItemView::ExtendedSelection); + _history_list_view->setContextMenuPolicy(Qt::CustomContextMenu); + connect(_history_list_view, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &))); + _filter_line_edit = new QLineEdit (this); _filter_line_edit->setStatusTip (tr ("Enter text to filter the command history.")); - QVBoxLayout *layout = new QVBoxLayout (); + QVBoxLayout *vbox_layout = new QVBoxLayout (); + setWindowIcon (QIcon(":/actions/icons/logo.png")); setWindowTitle (tr ("Command History")); setWidget (new QWidget ()); - layout->addWidget (_history_list_view); - layout->addWidget (_filter_line_edit); - layout->setMargin (2); + vbox_layout->addWidget (_history_list_view); + vbox_layout->addWidget (_filter_line_edit); + vbox_layout->setMargin (2); - widget ()->setLayout (layout); + widget ()->setLayout (vbox_layout); connect (_filter_line_edit, SIGNAL (textEdited (QString)), @@ -109,6 +86,9 @@ this, SLOT (handle_visibility_changed (bool))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); + _update_history_model_timer.setInterval (200); _update_history_model_timer.setSingleShot (true); @@ -122,10 +102,43 @@ setFocusProxy (_filter_line_edit); } +void history_dock_widget::ctxMenu(const QPoint &pos) { + QMenu *menu = new QMenu; + menu->addAction(tr("Copy"), this, SLOT(handle_contextmenu_copy(bool))); + menu->addAction(tr("Evaluate"), this, SLOT(handle_contextmenu_evaluate(bool))); + menu->exec(_history_list_view->mapToGlobal(pos)); +} + +void history_dock_widget::handle_contextmenu_copy(bool flag) +{ + QString text; + QItemSelectionModel *selectionModel = _history_list_view->selectionModel(); + QModelIndexList rows = selectionModel->selectedRows(); + QModelIndexList::iterator it; + for (it=rows.begin() ; it != rows.end(); it++) { + if ((*it).isValid()) { + text += (*it).data().toString()+"\n"; + } + } + QApplication::clipboard()->setText(text); +} + +void history_dock_widget::handle_contextmenu_evaluate(bool flag) +{ + QItemSelectionModel *selectionModel = _history_list_view->selectionModel(); + QModelIndexList rows = selectionModel->selectedRows(); + QModelIndexList::iterator it; + for (it=rows.begin() ; it != rows.end(); it++) { + if ((*it).isValid()) { + emit command_double_clicked ((*it).data().toString()+"\n"); + } + } +} + void history_dock_widget::handle_double_click (QModelIndex modelIndex) { - emit command_double_clicked (modelIndex.data().toString()); + emit command_double_clicked (modelIndex.data().toString()+"\n"); } void @@ -138,8 +151,7 @@ void history_dock_widget::request_history_model_update () { - octave_link::instance () - ->post_event (new octave_update_history_event (*this)); + octave_link::post_event (this, &history_dock_widget::update_history_callback); } void @@ -149,8 +161,64 @@ } void -history_dock_widget::closeEvent (QCloseEvent *event) +history_dock_widget::closeEvent (QCloseEvent *e) { emit active_changed (false); - QDockWidget::closeEvent (event); + QDockWidget::closeEvent (e); +} + +// slot for signal that is emitted when floating property changes +void +history_dock_widget::top_level_changed (bool floating) +{ + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlags hides it + } } + +void +history_dock_widget::update_history_callback (void) +{ + static bool scroll_window = false; + + // Determine the client's (our) history length and the one of the server. + int clientHistoryLength = _history_model->rowCount (); + int serverHistoryLength = command_history::length (); + + // If were behind the server, iterate through all new entries and add + // them to our history. + if (clientHistoryLength < serverHistoryLength) + { + int elts_to_add = serverHistoryLength - clientHistoryLength; + + _history_model->insertRows (clientHistoryLength, elts_to_add); + + for (int i = clientHistoryLength; i < serverHistoryLength; i++) + { + std::string entry = command_history::get_entry (i); + + _history_model->setData (_history_model->index (i), + QString::fromStdString (entry)); + } + + // FIXME -- does this behavior make sense? Calling + // _history_list_view->scrollToBottom () here doesn't seem to + // have any effect. Instead, we need to request that action + // and wait until the next event occurs in which no items + // are added to the history list. + + scroll_window = true; + } + else if (scroll_window) + { + scroll_window = false; + + _history_list_view->scrollToBottom (); + } + + // Post a new update event in a given time. This prevents flooding the + // event queue. + _update_history_model_timer.start (); +}
--- a/libgui/src/history-dockwidget.h +++ b/libgui/src/history-dockwidget.h @@ -30,28 +30,24 @@ #include <QStringListModel> #include <QTimer> -#include "octave-link.h" -#include "octave-event-observer.h" - -class history_dock_widget : public QDockWidget, public octave_event_observer +class history_dock_widget : public QDockWidget { -Q_OBJECT -public: + Q_OBJECT + public: history_dock_widget (QWidget *parent = 0); - void event_accepted (octave_event *e); - void event_reject (octave_event *e); - public slots: void handle_visibility_changed (bool visible); void request_history_model_update (); void reset_model (); + /** Slot when floating property changes */ + void top_level_changed (bool floating); signals: - void information (QString message); + void information (const QString& message); /** Emitted, whenever the user double-clicked a command in the history. */ - void command_double_clicked (QString command); + void command_double_clicked (const QString& command); /** Custom signal that tells if a user has clicked away that dock widget. */ void active_changed (bool active); @@ -59,6 +55,9 @@ void closeEvent (QCloseEvent *event); private slots: void handle_double_click (QModelIndex modelIndex); + void handle_contextmenu_copy(bool flag); + void handle_contextmenu_evaluate(bool flag); + void ctxMenu(const QPoint &pos); private: void construct (); @@ -70,6 +69,8 @@ QStringListModel *_history_model; QTimer _update_history_model_timer; + + void update_history_callback (void); }; #endif // HISTORYDOCKWIDGET_H
--- a/libgui/src/m-editor/file-editor-interface.h +++ b/libgui/src/m-editor/file-editor-interface.h @@ -35,49 +35,49 @@ Q_OBJECT public: - file_editor_interface (QTerminal *terminal, main_window *mainWindow) - : QDockWidget ((QWidget*)mainWindow) // QDockWidget constructor is explicit, hence the cast. - { - setObjectName ("FileEditor"); - _terminal = terminal; - _main_window = mainWindow; + file_editor_interface (QTerminal *terminal, main_window *mainWindow) + : QDockWidget ((QWidget*)mainWindow) // QDockWidget constructor is explicit, hence the cast. + { + setObjectName ("FileEditor"); + _terminal = terminal; + _main_window = mainWindow; - connect (this, SIGNAL (visibilityChanged (bool)), this, - SLOT (handle_visibility_changed (bool))); - } + connect (this, SIGNAL (visibilityChanged (bool)), this, + SLOT (handle_visibility_changed (bool))); + } - virtual ~file_editor_interface () { } + virtual ~file_editor_interface () { } - virtual QMenu *debug_menu () = 0; - virtual QToolBar *toolbar () = 0; + virtual QMenu *debug_menu () = 0; + virtual QToolBar *toolbar () = 0; - virtual void handle_entered_debug_mode () = 0; - virtual void handle_quit_debug_mode () = 0; + virtual void handle_entered_debug_mode () = 0; + virtual void handle_quit_debug_mode () = 0; - public slots: - virtual void request_new_file () = 0; - virtual void request_open_file () = 0; - virtual void request_open_file (QString fileName) = 0; +public slots: + virtual void request_new_file () = 0; + virtual void request_open_file () = 0; + virtual void request_open_file (const QString& fileName, bool silent = false) = 0; - signals: - void active_changed (bool active); +signals: + void active_changed (bool active); - protected: - QTerminal* _terminal; - main_window* _main_window; +protected: + QTerminal* _terminal; + main_window* _main_window; - void closeEvent (QCloseEvent *event) - { - emit active_changed (false); - QDockWidget::closeEvent (event); - } + void closeEvent (QCloseEvent *e) + { + emit active_changed (false); + QDockWidget::closeEvent (e); + } - protected slots: - void handle_visibility_changed (bool visible) - { - if (visible) - emit active_changed (true); - } +protected slots: + void handle_visibility_changed (bool visible) + { + if (visible) + emit active_changed (true); + } }; #endif // FILEEDITORINTERFACE_H
--- a/libgui/src/m-editor/file-editor-tab.cc +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -20,11 +20,9 @@ */ -#include "file-editor-tab.h" -#include "file-editor.h" -#include "find-dialog.h" -#include "octave-link.h" - +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #include <Qsci/qsciapis.h> // Not available in the Debian repos yet! @@ -36,16 +34,23 @@ #include <Qsci/qscilexerbatch.h> #include <Qsci/qscilexerdiff.h> #include "resource-manager.h" +#include <QApplication> +#include <QFileDialog> #include <QMessageBox> +#include <QTextStream> #include <QVBoxLayout> +#include "file-editor-tab.h" +#include "file-editor.h" +#include "find-dialog.h" +#include "octave-link.h" + +#include "debug.h" +#include "oct-env.h" + file_editor_tab::file_editor_tab(file_editor *fileEditor) - : QWidget ((QWidget*)fileEditor), octave_event_observer () + : QWidget ((QWidget*)fileEditor) { - QSettings *settings = resource_manager::get_settings (); - - // FIXME -- what should happen if settings is 0? - _file_editor = fileEditor; _file_name = ""; _edit_area = new QsciScintilla (this); @@ -67,43 +72,31 @@ // line numbers _edit_area->setMarginsForegroundColor(QColor(96,96,96)); _edit_area->setMarginsBackgroundColor(QColor(232,232,220)); - if (settings->value ("editor/showLineNumbers",true).toBool ()) - { - QFont marginFont( settings->value ("editor/fontName","Courier").toString () , - settings->value ("editor/fontSize",10).toInt () ); - _edit_area->setMarginsFont( marginFont ); - QFontMetrics metrics(marginFont); - _edit_area->setMarginType (2, QsciScintilla::TextMargin); - _edit_area->setMarginWidth(2, metrics.width("9999")); - _edit_area->setMarginLineNumbers (2, true); - } + _edit_area->setMarginType (2, QsciScintilla::TextMargin); // code folding _edit_area->setMarginType (3, QsciScintilla::SymbolMargin); _edit_area->setFolding (QsciScintilla::BoxedTreeFoldStyle , 3); + //highlight current line color + _edit_area->setCaretLineBackgroundColor(QColor(245,245,245)); + // other features - if (settings->value ("editor/highlightCurrentLine",true).toBool ()) - { - _edit_area->setCaretLineVisible(true); - _edit_area->setCaretLineBackgroundColor(QColor(245,245,245)); - } _edit_area->setBraceMatching (QsciScintilla::StrictBraceMatch); _edit_area->setAutoIndent (true); _edit_area->setIndentationWidth (2); _edit_area->setIndentationsUseTabs (false); - if (settings->value ("editor/codeCompletion",true).toBool ()) - { - _edit_area->autoCompleteFromAll (); - _edit_area->setAutoCompletionSource(QsciScintilla::AcsAll); - _edit_area->setAutoCompletionThreshold (1); - } + _edit_area->setUtf8 (true); - QVBoxLayout *layout = new QVBoxLayout (); - layout->addWidget (_edit_area); - layout->setMargin (0); - setLayout (layout); + // auto completion + _edit_area->autoCompleteFromAll (); + _edit_area->setAutoCompletionSource(QsciScintilla::AcsAll); + + QVBoxLayout *edit_area_layout = new QVBoxLayout (); + edit_area_layout->addWidget (_edit_area); + edit_area_layout->setMargin (0); + setLayout (edit_area_layout); // connect modified signal connect (_edit_area, SIGNAL (modificationChanged (bool)), @@ -114,7 +107,8 @@ this, SLOT (file_has_changed (QString))); _file_name = ""; - update_window_title (false); + + notice_settings (); } bool @@ -124,55 +118,13 @@ } void -file_editor_tab::event_accepted (octave_event *e) -{ - if (dynamic_cast<octave_run_file_event*> (e)) - { - // File was run successfully. - } - - if (octave_add_breakpoint_event *abe - = dynamic_cast<octave_add_breakpoint_event*> (e)) - { - // TODO: Check file. - _edit_area->markerAdd (abe->get_line (), breakpoint); - } - - if (octave_remove_breakpoint_event *rbe - = dynamic_cast<octave_remove_breakpoint_event*> (e)) - { - // TODO: Check file. - _edit_area->markerDelete (rbe->get_line (), breakpoint); - } - - if (octave_remove_all_breakpoints_event *rabe - = dynamic_cast<octave_remove_all_breakpoints_event*> (e)) - { - Q_UNUSED (rabe); - _edit_area->markerDeleteAll (breakpoint); - } - - delete e; -} - -void -file_editor_tab::event_reject (octave_event *e) -{ - if (dynamic_cast<octave_run_file_event*> (e)) - { - // Running file failed. - } - delete e; -} - -void -file_editor_tab::closeEvent (QCloseEvent *event) +file_editor_tab::closeEvent (QCloseEvent *e) { if (_file_editor->get_main_window ()->is_closing ()) { // close whole application: save file or not if modified check_file_modified ("Closing Octave", 0); // no cancel possible - event->accept (); + e->accept (); } else { @@ -181,42 +133,50 @@ if (check_file_modified ("Close File", QMessageBox::Cancel) == QMessageBox::Cancel) { - event->ignore (); + e->ignore (); } else { - event->accept(); + e->accept(); } } } void -file_editor_tab::set_file_name (QString fileName) +file_editor_tab::set_file_name (const QString& fileName) { + if (fileName != UNNAMED_FILE) + { + // update tracked file if wie really hae a file on disk + QStringList trackedFiles = _file_system_watcher.files (); + if (!trackedFiles.isEmpty ()) + _file_system_watcher.removePath (_file_name); + _file_system_watcher.addPath (fileName); + } _file_name = fileName; + + // update lexer after _file_name change update_lexer (); - update_tracked_file (); } void file_editor_tab::handle_margin_clicked(int margin, int line, Qt::KeyboardModifiers state) { - Q_UNUSED (state); if (margin == 1) { - unsigned int mask = _edit_area->markersAtLine (line); + unsigned int markers_mask = _edit_area->markersAtLine (line); if (state & Qt::ControlModifier) { - if (mask && (1 << bookmark)) + if (markers_mask && (1 << bookmark)) _edit_area->markerDelete(line,bookmark); else _edit_area->markerAdd(line,bookmark); } else { - if (mask && (1 << breakpoint)) + if (markers_mask && (1 << breakpoint)) { request_remove_breakpoint (line); } @@ -237,41 +197,16 @@ if (_file_name.endsWith (".m") || _file_name.endsWith (".M")) { lexer = new lexer_octave_gui (); - - // The API info that is used for auto completion - // TODO: Where to store a file with API info (raw or prepared?)? - // TODO: Also provide infos on octave-forge functions? - // TODO: Also provide infos on function parameters? - // By now, use the keywords-list from syntax highlighting - - QsciAPIs *lexer_api = new QsciAPIs (lexer); - - QString keyword; - QStringList keywordList; - - // get whole string with all keywords - keyword = lexer->keywords (1); - // split into single strings - keywordList = keyword.split (QRegExp ("\\s+")); - - int i; - for (i = 0; i < keywordList.size (); i++) - { - // add single strings to the API - lexer_api->add (keywordList.at (i)); - } - // prepare API info ... this make take some time - lexer_api->prepare (); } else if (_file_name.endsWith (".c") - || _file_name.endsWith (".cc") - || _file_name.endsWith (".cpp") - || _file_name.endsWith (".cxx") - || _file_name.endsWith (".c++") - || _file_name.endsWith (".h") - || _file_name.endsWith (".hh") - || _file_name.endsWith (".hpp") - || _file_name.endsWith (".h++")) + || _file_name.endsWith (".cc") + || _file_name.endsWith (".cpp") + || _file_name.endsWith (".cxx") + || _file_name.endsWith (".c++") + || _file_name.endsWith (".h") + || _file_name.endsWith (".hh") + || _file_name.endsWith (".hpp") + || _file_name.endsWith (".h++")) { lexer = new QsciLexerCPP (); } @@ -294,14 +229,13 @@ QSettings *settings = resource_manager::get_settings (); - // FIXME -- what should happen if settings is 0? - // Editor font (default or from settings) - lexer->setDefaultFont (QFont ( - settings->value ("editor/fontName", - "Courier").toString (), - settings->value ("editor/fontSize", - 10).toInt ())); + if (settings) + lexer->setDefaultFont (QFont ( + settings->value ("editor/fontName", + "Courier").toString (), + settings->value ("editor/fontSize", + 10).toInt ())); // TODO: Autoindent not working as it should lexer->setAutoIndentStyle (QsciScintilla::AiMaintain || @@ -321,11 +255,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_add_breakpoint_event (*this, - path.toStdString (), - function_name.toStdString (), - line)); + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::add_breakpoint_callback, info); } void @@ -338,11 +271,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_remove_breakpoint_event (*this, - path.toStdString (), - function_name.toStdString (), - line)); + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::remove_breakpoint_callback, info); } void @@ -417,24 +349,13 @@ emit editor_state_changed (); } -void -file_editor_tab::update_tracked_file () -{ - QStringList trackedFiles = _file_system_watcher.files (); - if (!trackedFiles.isEmpty ()) - _file_system_watcher.removePaths (trackedFiles); - - if (_file_name != UNNAMED_FILE) - _file_system_watcher.addPath (_file_name); -} - int -file_editor_tab::check_file_modified (QString msg, int cancelButton) +file_editor_tab::check_file_modified (const QString& msg, int cancelButton) { int decision = QMessageBox::Yes; if (_edit_area->isModified ()) { - // file is modified but not saved, aks user what to do + // file is modified but not saved, ask user what to do decision = QMessageBox::warning (this, msg, tr ("The file %1\n" @@ -510,10 +431,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_remove_all_breakpoints_event (*this, - path.toStdString (), - function_name.toStdString ())); + bp_info info (path, function_name, 0); + + octave_link::post_event + (this, &file_editor_tab::remove_all_breakpoints_callback, info); } void @@ -596,21 +517,21 @@ } bool -file_editor_tab::open_file () +file_editor_tab::open_file (const QString& dir) { QString openFileName; QFileDialog fileDialog(this); fileDialog.setNameFilter(SAVE_FILE_FILTER); fileDialog.setAcceptMode(QFileDialog::AcceptOpen); fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setDirectory(dir); if (fileDialog.exec () == QDialog::Accepted) { openFileName = fileDialog.selectedFiles().at(0); if (openFileName.isEmpty ()) return false; - load_file(openFileName); - return true; + return load_file(openFileName); } else { @@ -618,8 +539,8 @@ } } -void -file_editor_tab::load_file (QString fileName) +bool +file_editor_tab::load_file(const QString& fileName, bool silent) { if (!_file_editor->isVisible ()) { @@ -629,10 +550,11 @@ QFile file (fileName); if (!file.open (QFile::ReadOnly)) { - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("Could not open file %1 for read:\n%2.").arg (fileName). - arg (file.errorString ())); - return; + if (silent==false) + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("Could not open file %1 for read:\n%2.").arg (fileName). + arg (file.errorString ())); + return false; } QTextStream in (&file); @@ -641,11 +563,10 @@ QApplication::restoreOverrideCursor (); set_file_name (fileName); - update_tracked_file (); - - update_window_title (false); // window title (no modification) _edit_area->setModified (false); // loaded file is not modified yet + + return true; } void @@ -668,7 +589,7 @@ } bool -file_editor_tab::save_file (QString saveFileName) +file_editor_tab::save_file (const QString& saveFileName) { // it is a new file with the name "<unnamed>" -> call saveFielAs if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) @@ -676,10 +597,11 @@ return save_file_as(); } + // remove the file to save from the tracker since we will change it on disk now QStringList watched_files = _file_system_watcher.files(); if (!watched_files.isEmpty ()) - _file_system_watcher.removePaths(watched_files); - + _file_system_watcher.removePath(saveFileName); + // open the file for writing QFile file (saveFileName); if (!file.open (QFile::WriteOnly)) @@ -687,7 +609,6 @@ QMessageBox::warning (this, tr ("Octave Editor"), tr ("Could not open file %1 for write:\n%2."). arg (saveFileName).arg (file.errorString ())); - _file_system_watcher.addPaths (watched_files); return false; } @@ -696,17 +617,15 @@ QApplication::setOverrideCursor (Qt::WaitCursor); out << _edit_area->text (); QApplication::restoreOverrideCursor (); + file.close(); - // save file name for later use - _file_name = saveFileName; + // save file name after closing file otherwise tracker will notice file change + set_file_name (saveFileName); // set the window title to actual file name (not modified) update_window_title (false); - // files is save -> not modified + // files is save -> not modified _edit_area->setModified (false); - file.close(); - if (!watched_files.isEmpty ()) - _file_system_watcher.addPaths (watched_files); return true; } @@ -718,7 +637,7 @@ if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) { QString directory = QString::fromStdString - (octave_link::instance ()->get_last_working_directory ()); + (octave_link::last_working_directory ()); if (directory.isEmpty ()) { @@ -756,23 +675,22 @@ QFileInfo file_info (_file_name); QString path = file_info.absolutePath (); - //QString current_path = QString::fromStdString - (octave_link::instance ()->get_last_working_directory ()); + QString current_path + = QString::fromStdString (octave_link::last_working_directory ()); QString function_name = file_info.fileName (); // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); _file_editor->terminal ()->sendText (QString ("cd \'%1\'\n%2\n") - .arg(path).arg (function_name)); + .arg(path).arg (function_name)); // TODO: Sending a run event crashes for long scripts. Find out why. - // octave_link::instance () - // ->post_event (new octave_run_file_event (*this, _file_name.toStdString ())); + // octave_link::post_event + // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); } void -file_editor_tab::file_has_changed (QString fileName) +file_editor_tab::file_has_changed (const QString&) { - Q_UNUSED (fileName); if (QFile::exists (_file_name)) { // Prevent popping up multiple message boxes when the file has @@ -783,10 +701,10 @@ alreadyAsking = true; int decision = - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). - arg (_file_name), QMessageBox::Yes, - QMessageBox::No); + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). + arg (_file_name), QMessageBox::Yes, + QMessageBox::No); if (decision == QMessageBox::Yes) { @@ -799,10 +717,10 @@ else { int decision = - QMessageBox::warning (this, tr ("Octave Editor"), - tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). - arg (_file_name), QMessageBox::Save, - QMessageBox::Close); + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). + arg (_file_name), QMessageBox::Save, + QMessageBox::Close); if (decision == QMessageBox::Save) { if (!save_file_as ()) @@ -810,7 +728,6 @@ set_file_name (UNNAMED_FILE); update_window_title (true); // window title (no modification) set_modified (true); - update_tracked_file (); } } else @@ -819,3 +736,98 @@ } } } + +void +file_editor_tab::notice_settings () +{ + QSettings *settings = resource_manager::get_settings (); + + if (settings==NULL) + return; // this shouldn't happen! + + _edit_area->setCaretLineVisible(settings->value ("editor/highlightCurrentLine",true).toBool ()); + + if (settings->value ("editor/codeCompletion",true).toBool ()) + _edit_area->setAutoCompletionThreshold (1); + else + _edit_area->setAutoCompletionThreshold (-1); + + QFont font( settings->value ("editor/fontName","Courier").toString () , + settings->value ("editor/fontSize",10).toInt () ); + if (settings->value ("editor/showLineNumbers",true).toBool ()) + { + _edit_area->setMarginLineNumbers (2, true); + _edit_area->setMarginsFont( font ); + QFontMetrics metrics( font ); + _edit_area->setMarginWidth(2, metrics.width("9999")); + } + else + { + _edit_area->setMarginLineNumbers (2, false); + _edit_area->setMarginWidth(2, 0); + } + + update_lexer (); + + _long_title = settings->value ("editor/longWindowTitle",false).toBool (); + + update_window_title (false); +} + +void +file_editor_tab::run_file_callback (void) +{ + // Maybe someday we will do something here? +} + +void +file_editor_tab::add_breakpoint_callback (const bp_info& info) +{ + bp_table::intmap intmap; + intmap[0] = info.line + 1; + + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + intmap = bp_table::add_breakpoint (info.function_name, intmap); + octave_env::chdir (previous_directory); + + if (intmap.size () > 0) + { + // FIXME -- Check file. + _edit_area->markerAdd (info.line, breakpoint); + } +} + +void +file_editor_tab::remove_breakpoint_callback (const bp_info& info) +{ + bp_table::intmap intmap; + intmap[0] = info.line; + + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + bp_table::remove_breakpoint (info.function_name, intmap); + octave_env::chdir (previous_directory); + + // FIXME -- check result + bool success = true; + + if (success) + { + // FIXME -- check file. + _edit_area->markerDelete (info.line, breakpoint); + } +} + +void +file_editor_tab::remove_all_breakpoints_callback (const bp_info& info) +{ + bp_table::intmap intmap; + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + intmap = bp_table::remove_all_breakpoints_in_file (info.function_name, true); + octave_env::chdir (previous_directory); + + if (intmap.size() > 0) + _edit_area->markerDeleteAll (breakpoint); +}
--- a/libgui/src/m-editor/file-editor-tab.h +++ b/libgui/src/m-editor/file-editor-tab.h @@ -27,19 +27,15 @@ #include <QWidget> #include <QCloseEvent> #include <QFileSystemWatcher> -#include "octave-event-observer.h" class file_editor; -class file_editor_tab : public QWidget, public octave_event_observer +class file_editor_tab : public QWidget { Q_OBJECT -public: + public: file_editor_tab (file_editor *fileEditor); bool copy_available (); - void event_accepted (octave_event *e); - void event_reject (octave_event *e); - public slots: void update_window_title(bool modified); void handle_copy_available(bool enableCopy); @@ -64,34 +60,54 @@ void set_modified (bool modified = true); - bool open_file (); - void load_file (QString fileName); + bool open_file (const QString& dir = QString ()); + bool load_file (const QString& fileName, bool silent = false); void new_file (); bool save_file (); - bool save_file(QString saveFileName); + bool save_file (const QString& saveFileName); bool save_file_as(); void run_file (); - void file_has_changed (QString fileName); + void file_has_changed (const QString& fileName); + QString get_file_name () const {return _file_name;} + + /** Tells the editor tab to react on changed settings. */ + void notice_settings (); signals: - void file_name_changed (QString fileName); + void file_name_changed (const QString& fileName); void editor_state_changed (); void close_request (); protected: void closeEvent (QCloseEvent *event); - void set_file_name (QString fileName); + void set_file_name (const QString& fileName); private: + + struct bp_info + { + bp_info (const QString& p, const QString& fn, int l) + : path (p.toStdString ()), function_name (fn.toStdString ()), line (l) + { } + + std::string path; + std::string function_name; + int line; + }; + void update_lexer (); void request_add_breakpoint (int line); void request_remove_breakpoint (int line); - void update_tracked_file (); - int check_file_modified (QString msg, int cancelButton); + int check_file_modified (const QString& msg, int cancelButton); void do_comment_selected_text (bool comment); + void run_file_callback (void); + void add_breakpoint_callback (const bp_info& info); + void remove_breakpoint_callback (const bp_info& info); + void remove_all_breakpoints_callback (const bp_info& info); + file_editor * _file_editor; QsciScintilla * _edit_area;
--- a/libgui/src/m-editor/file-editor.cc +++ b/libgui/src/m-editor/file-editor.cc @@ -20,7 +20,12 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "file-editor.h" +#include "resource-manager.h" #include <QVBoxLayout> #include <QApplication> #include <QFile> @@ -30,18 +35,32 @@ #include <QStyle> #include <QTextStream> -file_editor::file_editor (QTerminal *terminal, main_window *m) - : file_editor_interface(terminal, m) +file_editor::file_editor (QTerminal *t, main_window *m) + : file_editor_interface (t, m) { construct (); - _terminal = terminal; + _terminal = t; _main_window = m; setVisible (false); } file_editor::~file_editor () { + QSettings *settings = resource_manager::get_settings (); + QStringList sessionFileNames; + if (settings->value ("editor/restoreSession",true).toBool ()) + { + for (int n=0;n<_tab_widget->count();++n) + { + file_editor_tab* tab = dynamic_cast<file_editor_tab*> (_tab_widget->widget (n)); + if (!tab) + continue; + sessionFileNames.append (tab->get_file_name ()); + } + } + settings->setValue ("editor/savedSessionTabs", sessionFileNames); + settings->sync (); } QTerminal * @@ -94,20 +113,29 @@ void file_editor::request_open_file () { + file_editor_tab *current_tab = active_editor_tab (); + int curr_tab_index = _tab_widget->currentIndex (); file_editor_tab *fileEditorTab = new file_editor_tab (this); if (fileEditorTab) { add_file_editor_tab (fileEditorTab); - if (!fileEditorTab->open_file ()) + QString dir = QDir::currentPath (); + // get the filename of the last active tab to open a new file from there + if (current_tab) + dir = QDir::cleanPath (current_tab->get_file_name ()); + if (!fileEditorTab->open_file (dir)) { // If no file was loaded, remove the tab again. _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); + // restore focus to previous tab + if (curr_tab_index>=0) + _tab_widget->setCurrentIndex (curr_tab_index); } } } void -file_editor::request_open_file (QString fileName) +file_editor::request_open_file (const QString& fileName, bool silent) { if (!isVisible ()) { @@ -115,10 +143,17 @@ } file_editor_tab *fileEditorTab = new file_editor_tab (this); + int curr_tab_index = _tab_widget->currentIndex (); if (fileEditorTab) { add_file_editor_tab (fileEditorTab); - fileEditorTab->load_file (fileName); + if (!fileEditorTab->load_file (fileName, silent)) + { + // If no file was loaded, remove the tab again. + _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); + // restore focus to previous tab + _tab_widget->setCurrentIndex (curr_tab_index); + } } } @@ -275,7 +310,7 @@ } void -file_editor::handle_file_name_changed (QString fileName) +file_editor::handle_file_name_changed (const QString& fileName) { QObject *senderObject = sender (); file_editor_tab *fileEditorTab @@ -317,10 +352,20 @@ } } +// slot for signal that is emitted when floating property changes void -file_editor::active_tab_changed (int index) +file_editor::top_level_changed (bool floating) { - Q_UNUSED (index); + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlag hides it + } +} + +void +file_editor::active_tab_changed (int) +{ handle_editor_state_changed (); } @@ -338,34 +383,46 @@ } void +file_editor::notice_settings () +{ + for(int i = 0; i < _tab_widget->count (); i++) + { + file_editor_tab *fileEditorTab + = dynamic_cast <file_editor_tab*> (_tab_widget->widget (i)); + if (fileEditorTab) + fileEditorTab->notice_settings (); + } +} + +void file_editor::construct () { - QWidget *widget = new QWidget (this); - QStyle *style = QApplication::style (); + QWidget *editor_widget = new QWidget (this); + QStyle *editor_style = QApplication::style (); - _menu_bar = new QMenuBar (widget); - _tool_bar = new QToolBar (widget); - _tab_widget = new QTabWidget (widget); + _menu_bar = new QMenuBar (editor_widget); + _tool_bar = new QToolBar (editor_widget); + _tab_widget = new QTabWidget (editor_widget); _tab_widget->setTabsClosable (true); QAction *new_action = new QAction (QIcon(":/actions/icons/filenew.png"), - tr("&New File"), _tool_bar); + tr("&New File"), _tool_bar); QAction *open_action = new QAction (QIcon(":/actions/icons/fileopen.png"), - tr("&Open File"), _tool_bar); + tr("&Open File"), _tool_bar); QAction *save_action = new QAction (QIcon(":/actions/icons/filesave.png"), - tr("&Save File"), _tool_bar); + tr("&Save File"), _tool_bar); QAction *save_as_action = new QAction (QIcon(":/actions/icons/filesaveas.png"), tr("Save File &As"), _tool_bar); QAction *undo_action = new QAction (QIcon(":/actions/icons/undo.png"), - tr("&Undo"), _tool_bar); + tr("&Undo"), _tool_bar); QAction *redo_action = new QAction (QIcon(":/actions/icons/redo.png"), - tr("&Redo"), _tool_bar); + tr("&Redo"), _tool_bar); _copy_action = new QAction (QIcon(":/actions/icons/editcopy.png"), tr ("&Copy"), _tool_bar); @@ -374,25 +431,25 @@ tr ("Cu&t"), _tool_bar); QAction *paste_action - = new QAction (QIcon (":/actions/icons/editpaste.png"), - tr("Paste"), _tool_bar); + = new QAction (QIcon (":/actions/icons/editpaste.png"), + tr("Paste"), _tool_bar); QAction *next_bookmark_action = new QAction (tr ("&Next Bookmark"),_tool_bar); QAction *previous_bookmark_action = new QAction (tr ("Pre&vious Bookmark"),_tool_bar); QAction *toggle_bookmark_action = new QAction (tr ("Toggle &Bookmark"),_tool_bar); QAction *remove_bookmark_action = new QAction (tr ("&Remove All Bookmarks"),_tool_bar); QAction *next_breakpoint_action - = new QAction (QIcon (":/actions/icons/bp_next.png"), - tr ("&Next breakpoint"), _tool_bar); + = new QAction (QIcon (":/actions/icons/bp_next.png"), + tr ("&Next breakpoint"), _tool_bar); QAction *previous_breakpoint_action - = new QAction (QIcon (":/actions/icons/bp_prev.png"), - tr ("Pre&vious breakpoint"), _tool_bar); + = new QAction (QIcon (":/actions/icons/bp_prev.png"), + tr ("Pre&vious breakpoint"), _tool_bar); QAction *toggle_breakpoint_action - = new QAction (QIcon (":/actions/icons/bp_toggle.png"), - tr ("Toggle &breakpoint"), _tool_bar); + = new QAction (QIcon (":/actions/icons/bp_toggle.png"), + tr ("Toggle &breakpoint"), _tool_bar); QAction *remove_all_breakpoints_action - = new QAction (QIcon (":/actions/icons/bp_rm_all.png"), - tr ("&Remove All breakpoints"), _tool_bar); + = new QAction (QIcon (":/actions/icons/bp_rm_all.png"), + tr ("&Remove All breakpoints"), _tool_bar); QAction *comment_selection_action = new QAction (tr ("&Comment Selected Text"),_tool_bar); QAction *uncomment_selection_action = new QAction (tr ("&Uncomment Selected Text"),_tool_bar); @@ -401,7 +458,7 @@ tr ("&Find and Replace"), _tool_bar); _run_action = new QAction (QIcon(":/actions/icons/artsbuilderexecute.png"), - tr("Save File And Run"), _tool_bar); + tr("Save File And Run"), _tool_bar); // some actions are disabled from the beginning _copy_action->setEnabled(false); @@ -482,17 +539,17 @@ _run_menu->addAction (_run_action); _menu_bar->addMenu (_run_menu); - QVBoxLayout *layout = new QVBoxLayout (); - layout->addWidget (_menu_bar); - layout->addWidget (_tool_bar); - layout->addWidget (_tab_widget); - layout->setMargin (0); - widget->setLayout (layout); - setWidget (widget); + QVBoxLayout *vbox_layout = new QVBoxLayout (); + vbox_layout->addWidget (_menu_bar); + vbox_layout->addWidget (_tool_bar); + vbox_layout->addWidget (_tab_widget); + vbox_layout->setMargin (0); + editor_widget->setLayout (vbox_layout); + setWidget (editor_widget); connect (new_action, SIGNAL (triggered ()), this, SLOT (request_new_file ())); - connect (open_action, + connect (open_action, SIGNAL (triggered ()), this, SLOT (request_open_file ())); connect (undo_action, SIGNAL (triggered ()), this, SLOT (request_undo ())); @@ -536,11 +593,22 @@ SIGNAL (tabCloseRequested (int)), this, SLOT (handle_tab_close_request (int))); connect (_tab_widget, SIGNAL (currentChanged(int)), this, SLOT (active_tab_changed (int))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); resize (500, 400); - setWindowIcon (QIcon::fromTheme ("accessories-text-editor", - style->standardIcon (QStyle::SP_FileIcon))); - setWindowTitle ("Octave Editor"); + setWindowIcon (QIcon(":/actions/icons/logo.png")); + setWindowTitle ("Editor"); + + //restore previous session + QSettings *settings = resource_manager::get_settings (); + if (settings->value ("editor/restoreSession",true).toBool ()) + { + QStringList sessionFileNames = settings->value("editor/savedSessionTabs", QStringList()).toStringList (); + + for (int n=0; n < sessionFileNames.count (); ++n) + request_open_file (sessionFileNames.at (n), true); + } } void
--- a/libgui/src/m-editor/file-editor.h +++ b/libgui/src/m-editor/file-editor.h @@ -45,12 +45,12 @@ class file_editor : public file_editor_interface { -Q_OBJECT + Q_OBJECT -public: + public: file_editor (QTerminal *terminal, main_window *m); ~file_editor (); - void loadFile (QString fileName); + void loadFile (const QString& fileName); QTerminal * terminal (); main_window * get_main_window (); @@ -64,7 +64,7 @@ public slots: void request_new_file (); void request_open_file (); - void request_open_file (QString fileName); + void request_open_file (const QString& fileName, bool silent = false); void request_undo (); void request_redo (); @@ -88,11 +88,16 @@ void request_uncomment_selected_text (); void request_find (); - void handle_file_name_changed (QString fileName); + void handle_file_name_changed (const QString& fileName); void handle_tab_close_request (int index); void handle_tab_close_request (); void active_tab_changed (int index); void handle_editor_state_changed (); + /** Slot when floating property changes */ + void top_level_changed (bool floating); + + /** Tells the editor to react on changed settings. */ + void notice_settings (); private: void construct ();
--- a/libgui/src/m-editor/find-dialog.cc +++ b/libgui/src/m-editor/find-dialog.cc @@ -39,12 +39,16 @@ ** ****************************************************************************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <QtGui> #include <QIcon> #include "find-dialog.h" -find_dialog::find_dialog (QsciScintilla* edit_area, QWidget *parent) - : QDialog (parent) +find_dialog::find_dialog (QsciScintilla* edit_area, QWidget *p) + : QDialog (p) { setWindowTitle ("Find and Replace"); setWindowIcon (QIcon(":/actions/icons/logo.png")); @@ -139,15 +143,17 @@ if (_edit_area) { _find_result_available = _edit_area->findFirst (_search_line_edit->text (), - _regex_check_box->isChecked (), - _case_check_box->isChecked (), - _whole_words_check_box->isChecked (), - _wrap_check_box->isChecked (), - !_backward_check_box->isChecked (), - line,col, - true, - true - ); + _regex_check_box->isChecked (), + _case_check_box->isChecked (), + _whole_words_check_box->isChecked (), + _wrap_check_box->isChecked (), + !_backward_check_box->isChecked (), + line,col, + true +#ifdef HAVE_FINDFIRST_MODERN + , true +#endif + ); } }
--- a/libgui/src/m-editor/find-dialog.h +++ b/libgui/src/m-editor/find-dialog.h @@ -55,7 +55,7 @@ class find_dialog : public QDialog { Q_OBJECT -public: + public: find_dialog (QsciScintilla* edit_area, QWidget *parent = 0); private slots:
--- a/libgui/src/m-editor/lexer-octave-gui.cc +++ b/libgui/src/m-editor/lexer-octave-gui.cc @@ -20,6 +20,10 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "lexer-octave-gui.h" #include <qcolor.h> #include <qfont.h> @@ -27,13 +31,40 @@ // ----------------------------------------------------- // Some basic functions // ----------------------------------------------------- -lexer_octave_gui::lexer_octave_gui(QObject *parent) - : QsciLexer(parent) // inherit from base lexer +lexer_octave_gui::lexer_octave_gui (QObject *p) + : QsciLexer (p) { + // The API info that is used for auto completion + // TODO: Where to store a file with API info (raw or prepared?)? + // TODO: Also provide infos on octave-forge functions? + // TODO: Also provide infos on function parameters? + // By now, use the keywords-list from syntax highlighting + + QString keyword; + QStringList keywordList; + + // get whole string with all keywords + keyword = this->keywords (1); + // split into single strings + keywordList = keyword.split (QRegExp ("\\s+")); + + lexer_api = new QsciAPIs (this); + if (lexer_api) + { + for (int i = 0; i < keywordList.size (); i++) + { + // add single strings to the API + lexer_api->add (keywordList.at (i)); + } + // prepare API info ... this may take some time + lexer_api->prepare (); + } } lexer_octave_gui::~lexer_octave_gui() { + if (lexer_api) + delete lexer_api; } const char *lexer_octave_gui::language() const @@ -51,26 +82,26 @@ // ----------------------------------------------------- QColor lexer_octave_gui::defaultColor(int style) const { - switch (style) - { - case Default: // black - return QColor(0x00,0x00,0x00); - case Operator: // red - return QColor(0xef,0x00,0x00); - case Comment: // gray - return QColor(0x7f,0x7f,0x7f); - case Command: // blue-green - return QColor(0x00,0x7f,0x7f); - case Number: // orange - return QColor(0x7f,0x7f,0x00); - case Keyword: // blue - return QColor(0x00,0x00,0xbf); - case SingleQuotedString: // green - return QColor(0x00,0x7f,0x00); - case DoubleQuotedString: // green-yellow - return QColor(0x4f,0x7f,0x00); - } - return QsciLexer::defaultColor(style); + switch (style) + { + case Default: // black + return QColor(0x00,0x00,0x00); + case Operator: // red + return QColor(0xef,0x00,0x00); + case Comment: // gray + return QColor(0x7f,0x7f,0x7f); + case Command: // blue-green + return QColor(0x00,0x7f,0x7f); + case Number: // orange + return QColor(0x7f,0x7f,0x00); + case Keyword: // blue + return QColor(0x00,0x00,0xbf); + case SingleQuotedString: // green + return QColor(0x00,0x7f,0x00); + case DoubleQuotedString: // green-yellow + return QColor(0x4f,0x7f,0x00); + } + return QsciLexer::defaultColor(style); } @@ -79,25 +110,25 @@ // ----------------------------------------------------- QFont lexer_octave_gui::defaultFont(int style) const { - QFont f; + QFont f; - switch (style) - { - case Comment: // default but italic - f = QsciLexer::defaultFont(style); - f.setItalic(true); - break; - case Keyword: // default - f = QsciLexer::defaultFont(style); - break; - case Operator: // default - f = QsciLexer::defaultFont(style); - break; - default: // default - f = QsciLexer::defaultFont(style); - break; - } - return f; // return the selected font + switch (style) + { + case Comment: // default but italic + f = QsciLexer::defaultFont(style); + f.setItalic(true); + break; + case Keyword: // default + f = QsciLexer::defaultFont(style); + break; + case Operator: // default + f = QsciLexer::defaultFont(style); + break; + default: // default + f = QsciLexer::defaultFont(style); + break; + } + return f; // return the selected font } @@ -106,28 +137,28 @@ // ----------------------------------------------------- QString lexer_octave_gui::description(int style) const { - switch (style) - { - case Default: - return tr("Default"); - case Comment: - return tr("Comment"); - case Command: - return tr("Command"); - case Number: - return tr("Number"); - case Keyword: - return tr("Keyword"); - case SingleQuotedString: - return tr("Single-quoted string"); - case Operator: - return tr("Operator"); - case Identifier: - return tr("Identifier"); - case DoubleQuotedString: - return tr("Double-quoted string"); - } - return QString(); + switch (style) + { + case Default: + return tr("Default"); + case Comment: + return tr("Comment"); + case Command: + return tr("Command"); + case Number: + return tr("Number"); + case Keyword: + return tr("Keyword"); + case SingleQuotedString: + return tr("Single-quoted string"); + case Operator: + return tr("Operator"); + case Identifier: + return tr("Identifier"); + case DoubleQuotedString: + return tr("Double-quoted string"); + } + return QString(); } @@ -137,10 +168,10 @@ // ----------------------------------------------------- const char *lexer_octave_gui::keywords(int set) const { - if (set == 1) - { - return resource_manager::octave_keywords (); - } - return 0; + if (set == 1) + { + return resource_manager::octave_keywords (); + } + return 0; }
--- a/libgui/src/m-editor/lexer-octave-gui.h +++ b/libgui/src/m-editor/lexer-octave-gui.h @@ -27,39 +27,40 @@ #include <QObject> #include <Qsci/qsciglobal.h> #include <Qsci/qscilexer.h> - +#include <Qsci/qsciapis.h> class lexer_octave_gui : public QsciLexer { - Q_OBJECT + Q_OBJECT -public: - // the used styles - enum - { - Default = 0, - Comment = 1, - Command = 2, - Number = 3, - Keyword = 4, - SingleQuotedString = 5, - Operator = 6, - Identifier = 7, - DoubleQuotedString = 8 - }; + public: + // the used styles + enum + { + Default = 0, + Comment = 1, + Command = 2, + Number = 3, + Keyword = 4, + SingleQuotedString = 5, + Operator = 6, + Identifier = 7, + DoubleQuotedString = 8 + }; - lexer_octave_gui (QObject *parent = 0); - virtual ~lexer_octave_gui (); - const char *language () const; - const char *lexer () const; - QColor defaultColor (int style) const; - QFont defaultFont (int style) const; - const char *keywords (int set) const; - QString description (int style) const; + lexer_octave_gui (QObject *parent = 0); + ~lexer_octave_gui (); + const char *language () const; + const char *lexer () const; + QColor defaultColor (int style) const; + QFont defaultFont (int style) const; + const char *keywords (int set) const; + QString description (int style) const; private: - lexer_octave_gui (const lexer_octave_gui &); - lexer_octave_gui &operator= (const lexer_octave_gui &); + lexer_octave_gui (const lexer_octave_gui &); + lexer_octave_gui &operator= (const lexer_octave_gui &); + QsciAPIs *lexer_api; }; #endif
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -20,6 +20,12 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <QApplication> +#include <QLabel> #include <QMenuBar> #include <QMenu> #include <QAction> @@ -31,16 +37,26 @@ #include <QMessageBox> #include <QIcon> +#include "file-editor.h" #include "main-window.h" -#include "file-editor.h" +#include "octave-link.h" #include "settings-dialog.h" -main_window::main_window (QWidget * parent) - : QMainWindow (parent), octave_event_observer () +#include "builtins.h" +#include "defaults.h" +#include "load-save.h" +#include "toplev.h" +#include "version.h" + +#include "cmd-hist.h" +#include "oct-env.h" + +main_window::main_window (QWidget *p) + : QMainWindow (p) { // We have to set up all our windows, before we finally launch octave. construct (); - octave_link::instance ()->launch_octave(); + octave_link::launch_octave (); } main_window::~main_window () @@ -48,23 +64,6 @@ } void -main_window::event_accepted (octave_event *e) -{ - if (dynamic_cast<octave_clear_history_event*> (e)) - { - // After clearing the history, we need to reset the model. - _history_dock_widget->reset_model (); - } - delete e; -} - -void -main_window::event_reject (octave_event *e) -{ - delete e; -} - -void main_window::new_file () { _file_editor->request_new_file (); @@ -79,14 +78,14 @@ } void -main_window::open_file (QString file_name) +main_window::open_file (const QString& file_name) { _file_editor->request_open_file (file_name); focus_editor (); } void -main_window::report_status_message (QString statusMessage) +main_window::report_status_message (const QString& statusMessage) { _status_bar->showMessage (statusMessage, 1000); } @@ -95,46 +94,38 @@ main_window::handle_save_workspace_request () { QString selectedFile = - QFileDialog::getSaveFileName (this, tr ("Save Workspace"), - resource_manager::get_home_path ()); + QFileDialog::getSaveFileName (this, tr ("Save Workspace"), + resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) - { - octave_link::instance () - ->post_event (new octave_save_workspace_event (*this, - selectedFile.toStdString())); - } + octave_link::post_event (this, &main_window::save_workspace_callback, + selectedFile.toStdString ()); } void main_window::handle_load_workspace_request () { QString selectedFile = - QFileDialog::getOpenFileName (this, tr ("Load Workspace"), - resource_manager::get_home_path ()); + QFileDialog::getOpenFileName (this, tr ("Load Workspace"), + resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) - { - octave_link::instance () - ->post_event (new octave_load_workspace_event (*this, - selectedFile.toStdString())); - } + octave_link::post_event (this, &main_window::load_workspace_callback, + selectedFile.toStdString ()); } void main_window::handle_clear_workspace_request () { - octave_link::instance () - ->post_event (new octave_clear_workspace_event (*this)); + octave_link::post_event (this, &main_window::clear_workspace_callback); } void main_window::handle_clear_history_request() { - octave_link::instance () - ->post_event (new octave_clear_history_event (*this)); + octave_link::post_event (this, &main_window::clear_history_callback); } void -main_window::handle_command_double_clicked (QString command) +main_window::handle_command_double_clicked (const QString& command) { _terminal->sendText (command); _terminal->setFocus (); @@ -162,9 +153,13 @@ main_window::process_settings_dialog_request () { settings_dialog *settingsDialog = new settings_dialog (this); - settingsDialog->exec (); + int change_settings = settingsDialog->exec (); + if (change_settings == QDialog::Accepted) + { + settingsDialog->write_changed_settings (); + emit settings_changed (); + } delete settingsDialog; - emit settings_changed (); } void @@ -175,10 +170,10 @@ // FIXME -- what should happen if settings is 0? - QFont font = QFont(); - font.setFamily(settings->value("terminal/fontName").toString()); - font.setPointSize(settings->value("terminal/fontSize").toInt ()); - _terminal->setTerminalFont(font); + QFont term_font = QFont(); + term_font.setFamily(settings->value("terminal/fontName").toString()); + term_font.setPointSize(settings->value("terminal/fontSize").toInt ()); + _terminal->setTerminalFont (term_font); QString cursorType = settings->value ("terminal/cursorType").toString (); bool cursorBlinking = settings->value ("terminal/cursorBlinking").toBool (); @@ -206,16 +201,15 @@ } void -main_window::current_working_directory_has_changed (QString directory) +main_window::current_working_directory_has_changed (const QString& directory) { - if (_current_directory_combo_box->count () > 31) - { - _current_directory_combo_box->removeItem (0); + int index = _current_directory_combo_box->findText (directory); + if ( index >= 0 ) // directory already in list -> remove it + { + _current_directory_combo_box->removeItem (index); } - _current_directory_combo_box->addItem (directory); - int index = _current_directory_combo_box->findText (directory); - _current_directory_combo_box->setCurrentIndex (index); - + _current_directory_combo_box->insertItem (0,directory); // add (on top) + _current_directory_combo_box->setCurrentIndex (0); // top is actual _files_dock_widget->set_current_directory (directory); } @@ -223,22 +217,18 @@ main_window::change_current_working_directory () { QString selectedDirectory = - QFileDialog::getExistingDirectory(this, tr ("Set working direcotry")); + QFileDialog::getExistingDirectory(this, tr ("Set working direcotry")); if (!selectedDirectory.isEmpty ()) - { - octave_link::instance () - ->post_event (new octave_change_directory_event (*this, - selectedDirectory.toStdString ())); - } + octave_link::post_event (this, &main_window::change_directory_callback, + selectedDirectory.toStdString ()); } void -main_window::set_current_working_directory (QString directory) +main_window::set_current_working_directory (const QString& directory) { - octave_link::instance () - ->post_event (new octave_change_directory_event (*this, - directory.toStdString ())); + octave_link::post_event (this, &main_window::change_directory_callback, + directory.toStdString ()); } void @@ -356,67 +346,47 @@ void main_window::debug_continue () { - octave_link::instance () - ->post_event (new octave_debug_continue_event (*this)); + octave_link::post_event (this, &main_window::debug_continue_callback); } void main_window::debug_step_into () { - octave_link::instance () - ->post_event (new octave_debug_step_into_event (*this)); + octave_link::post_event (this, &main_window::debug_step_into_callback); } void main_window::debug_step_over () { - octave_link::instance () - ->post_event (new octave_debug_step_over_event (*this)); + octave_link::post_event (this, &main_window::debug_step_over_callback); } void main_window::debug_step_out () { - octave_link::instance () - ->post_event (new octave_debug_step_out_event (*this)); + octave_link::post_event (this, &main_window::debug_step_out_callback); } void main_window::debug_quit () { - octave_link::instance () - ->post_event (new octave_debug_quit_event (*this)); + octave_link::post_event (this, &main_window::debug_quit_callback); } void main_window::show_about_octave () { - QString message = - "GNU Octave\n" - "Copyright (C) 2009 John W. Eaton and others.\n" - "This is free software; see the source code for copying conditions." - "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or" - "FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'.\n" - "\n" - "Additional information about Octave is available at http://www.octave.org.\n" - "\n" - "Please contribute if you find this software useful." - "For more information, visit http://www.octave.org/help-wanted.html\n" - "\n" - "Report bugs to <bug@octave.org> (but first, please read" - "http://www.octave.org/bugs.html to learn how to write a helpful report).\n" - "\n" - "For information about changes from previous versions, type `news'.\n"; + QString message = OCTAVE_STARTUP_MESSAGE; QMessageBox::about (this, tr ("About Octave"), message); } void -main_window::closeEvent (QCloseEvent * closeEvent) +main_window::closeEvent (QCloseEvent *e) { - closeEvent->ignore (); - octave_link::instance ()->post_event (new octave_exit_event (*this)); - } + e->ignore (); + octave_link::post_event (this, &main_window::exit_callback); +} void main_window::read_settings () @@ -425,8 +395,32 @@ // FIXME -- what should happen if settings is 0? + restoreState (settings->value ("MainWindow/windowState").toByteArray ()); + settings->beginGroup ("DockWidgets"); + // restoring the geometry of all dock-widgets + foreach (QObject *obj, children ()) + { + QString name = obj->objectName (); + if (obj->inherits("QDockWidget") && ! name.isEmpty ()) + { + QDockWidget *widget = qobject_cast<QDockWidget *> (obj); + QVariant val = settings->value (name); + widget->restoreGeometry (val.toByteArray ()); + bool floating = settings->value (name+"Floating",false).toBool (); + bool visible = settings->value (name+"Visible",true).toBool (); + if (floating) + widget->setWindowFlags (Qt::Window); // if floating, make window from widget + widget->setVisible (visible); // make widget visible if desired (setWindowFlags hides widget) + } + } + settings->endGroup(); restoreGeometry (settings->value ("MainWindow/geometry").toByteArray ()); - restoreState (settings->value ("MainWindow/windowState").toByteArray ()); + // restore the list of the last directories + QStringList curr_dirs = settings->value ("MainWindow/current_directory_list").toStringList (); + for (int i=0; i < curr_dirs.size (); i++) + { + _current_directory_combo_box->addItem (curr_dirs.at (i)); + } emit settings_changed (); } @@ -438,7 +432,32 @@ // FIXME -- what should happen if settings is 0? settings->setValue ("MainWindow/geometry", saveGeometry ()); + settings->beginGroup ("DockWidgets"); + // saving the geometry of all widgets + foreach (QObject *obj, children()) + { + QString name = obj->objectName (); + if (obj->inherits ("QDockWidget") && ! name.isEmpty ()) + { + QDockWidget *widget = qobject_cast<QDockWidget *> (obj); + settings->setValue (name, widget->saveGeometry ()); + bool floating = widget->isFloating (); + bool visible = widget->isVisible (); + settings->setValue (name+"Floating",floating); // store floating state + settings->setValue (name+"Visible",visible); // store visibility + if (floating) + widget->setWindowFlags(Qt::Widget); // if floating, recover the widget state such that the widget's + } // state is correctly saved by the saveSate () below + } + settings->endGroup(); settings->setValue ("MainWindow/windowState", saveState ()); + // write the list of recent used directories + QStringList curr_dirs; + for (int i=0; i<_current_directory_combo_box->count (); i++) + { + curr_dirs.append (_current_directory_combo_box->itemText (i)); + } + settings->setValue ("MainWindow/current_directory_list",curr_dirs); settings->sync (); } @@ -463,7 +482,8 @@ _current_directory_combo_box->setFixedWidth (300); _current_directory_combo_box->setEditable (true); _current_directory_combo_box->setInsertPolicy (QComboBox::InsertAtTop); - _current_directory_combo_box->setMaxVisibleItems (14); + _current_directory_combo_box->setMaxVisibleItems (16); + _current_directory_combo_box->setMaxCount (16); _current_directory_tool_button = new QToolButton (this); _current_directory_tool_button->setIcon (QIcon(":/actions/icons/search.png")); @@ -492,7 +512,7 @@ QMenu *new_menu = file_menu->addMenu(tr ("New")); QAction *new_script_action - = new_menu->addAction (QIcon(":/actions/icons/filenew.png"), tr ("Script")); + = new_menu->addAction (QIcon(":/actions/icons/filenew.png"), tr ("Script")); new_script_action->setShortcut (Qt::ControlModifier + Qt::Key_N); QAction *new_function_action = new_menu->addAction (tr ("Function")); @@ -511,37 +531,37 @@ new_gui_action->setEnabled (false); // TODO: Make this work. QAction *open_action - = file_menu->addAction (QIcon(":/actions/icons/fileopen.png"), tr ("Open...")); + = file_menu->addAction (QIcon(":/actions/icons/fileopen.png"), tr ("Open...")); open_action->setShortcut (Qt::ControlModifier + Qt::Key_O); QAction *close_command_window_action - = file_menu->addAction (tr ("Close Command Window")); + = file_menu->addAction (tr ("Close Command Window")); close_command_window_action->setShortcut (Qt::ControlModifier + Qt::Key_W); close_command_window_action->setEnabled (false); // TODO: Make this work. file_menu->addSeparator (); QAction *import_data_action - = file_menu->addAction (tr ("Import Data...")); + = file_menu->addAction (tr ("Import Data...")); import_data_action->setEnabled (false); // TODO: Make this work. QAction *save_workspace_action - = file_menu->addAction (tr ("Save Workspace...")); + = file_menu->addAction (tr ("Save Workspace...")); save_workspace_action->setShortcut (Qt::ControlModifier + Qt::Key_S); file_menu->addSeparator (); QAction *preferences_action - = file_menu->addAction (QIcon(":/actions/icons/configure.png"), - tr ("Preferences...")); + = file_menu->addAction (QIcon(":/actions/icons/configure.png"), + tr ("Preferences...")); file_menu->addSeparator (); QAction *page_setup_action - = file_menu->addAction (tr ("Page Setup...")); + = file_menu->addAction (tr ("Page Setup...")); page_setup_action->setEnabled (false); // TODO: Make this work. QAction *print_action - = file_menu->addAction (tr ("Print")); + = file_menu->addAction (tr ("Print")); print_action->setShortcut (Qt::ControlModifier + Qt::Key_P); print_action->setEnabled (false); // TODO: Make this work. QAction *print_selection_action - = file_menu->addAction (tr ("Print Selection...")); + = file_menu->addAction (tr ("Print Selection...")); print_selection_action->setEnabled (false); // TODO: Make this work. file_menu->addSeparator (); @@ -551,57 +571,57 @@ QMenu *edit_menu = menuBar ()->addMenu (tr ("&Edit")); QAction *undo_action - = edit_menu->addAction (QIcon(":/actions/icons/undo.png"), tr ("Undo")); + = edit_menu->addAction (QIcon(":/actions/icons/undo.png"), tr ("Undo")); undo_action->setShortcut (QKeySequence::Undo); QAction *redo_action - = edit_menu->addAction (QIcon(":/actions/icons/redo.png"), tr ("Redo")); + = edit_menu->addAction (QIcon(":/actions/icons/redo.png"), tr ("Redo")); redo_action->setShortcut (QKeySequence::Redo); edit_menu->addSeparator (); QAction *cut_action - = edit_menu->addAction (QIcon(":/actions/icons/editcut.png"), tr ("Cut")); + = edit_menu->addAction (QIcon(":/actions/icons/editcut.png"), tr ("Cut")); cut_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_X); QAction *copy_action - = edit_menu->addAction (QIcon(":/actions/icons/editcopy.png"), tr ("Copy")); + = edit_menu->addAction (QIcon(":/actions/icons/editcopy.png"), tr ("Copy")); copy_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_C); QAction *paste_action - = edit_menu->addAction (QIcon(":/actions/icons/editpaste.png"), tr ("Paste")); + = edit_menu->addAction (QIcon(":/actions/icons/editpaste.png"), tr ("Paste")); paste_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_V); QAction *paste_to_workspace_action - = edit_menu->addAction (tr ("Paste To Workspace...")); + = edit_menu->addAction (tr ("Paste To Workspace...")); paste_to_workspace_action->setEnabled (false); // TODO: Make this work. edit_menu->addSeparator (); QAction *select_all_action - = edit_menu->addAction (tr ("Select All")); + = edit_menu->addAction (tr ("Select All")); select_all_action->setEnabled (false); // TODO: Make this work. QAction *delete_action - = edit_menu->addAction (tr ("Delete")); + = edit_menu->addAction (tr ("Delete")); delete_action->setShortcut (Qt::Key_Delete); delete_action->setEnabled (false); // TODO: Make this work. edit_menu->addSeparator (); QAction *find_action - = edit_menu->addAction (tr ("Find...")); + = edit_menu->addAction (tr ("Find...")); find_action->setEnabled (false); // TODO: Make this work. QAction *find_files_action - = edit_menu->addAction (tr ("Find Files...")); + = edit_menu->addAction (tr ("Find Files...")); find_files_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_F); find_files_action->setEnabled (false); // TODO: Make this work. edit_menu->addSeparator (); QAction *clear_command_window_action - = edit_menu->addAction (tr ("Clear Command Window")); + = edit_menu->addAction (tr ("Clear Command Window")); clear_command_window_action->setEnabled (false); // TODO: Make this work. QAction *clear_command_history - = edit_menu->addAction(tr ("Clear Command History")); + = edit_menu->addAction(tr ("Clear Command History")); QAction * clear_workspace_action - = edit_menu->addAction (tr ("Clear Workspace")); + = edit_menu->addAction (tr ("Clear Workspace")); _debug_menu = menuBar ()->addMenu (tr ("De&bug")); @@ -677,7 +697,7 @@ QAction * show_documentation_action = window_menu->addAction (tr ("Show Documentation")); show_documentation_action->setCheckable (true); show_documentation_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier - + Qt::Key_5); + + Qt::Key_5); window_menu->addSeparator (); QAction * command_window_action @@ -724,19 +744,19 @@ // Toolbars QToolBar *main_tool_bar = addToolBar ("Main"); - main_tool_bar->addAction (new_script_action); - main_tool_bar->addAction (open_action); - main_tool_bar->addSeparator (); - main_tool_bar->addAction (cut_action); - main_tool_bar->addAction (copy_action); - main_tool_bar->addAction (paste_action); - main_tool_bar->addAction (undo_action); - main_tool_bar->addAction (redo_action); - main_tool_bar->addSeparator (); - main_tool_bar->addWidget (new QLabel (tr ("Current Directory:"))); - main_tool_bar->addWidget (_current_directory_combo_box); - main_tool_bar->addWidget (_current_directory_tool_button); - main_tool_bar->addWidget (_current_directory_up_tool_button); + main_tool_bar->addAction (new_script_action); + main_tool_bar->addAction (open_action); + main_tool_bar->addSeparator (); + main_tool_bar->addAction (cut_action); + main_tool_bar->addAction (copy_action); + main_tool_bar->addAction (paste_action); + main_tool_bar->addAction (undo_action); + main_tool_bar->addAction (redo_action); + main_tool_bar->addSeparator (); + main_tool_bar->addWidget (new QLabel (tr ("Current Directory:"))); + main_tool_bar->addWidget (_current_directory_combo_box); + main_tool_bar->addWidget (_current_directory_tool_button); + main_tool_bar->addWidget (_current_directory_up_tool_button); connect (qApp, SIGNAL (aboutToQuit ()), this, SLOT (prepare_for_quit ())); @@ -797,6 +817,8 @@ connect (reset_windows_action, SIGNAL (triggered ()), this, SLOT (reset_windows ())); connect (this, SIGNAL (settings_changed ()), + _file_editor, SLOT (notice_settings ())); + connect (this, SIGNAL (settings_changed ()), _files_dock_widget, SLOT (notice_settings ())); connect (this, SIGNAL (settings_changed ()), this, SLOT (notice_settings ())); @@ -847,10 +869,9 @@ addDockWidget (Qt::BottomDockWidgetArea, _terminal_dock_widget); addDockWidget (Qt::RightDockWidgetArea, _documentation_dock_widget); setStatusBar (_status_bar); - read_settings (); _octave_qt_event_listener = new octave_qt_event_listener (); - octave_link::instance ()->register_event_listener (_octave_qt_event_listener); + octave_link::register_event_listener (_octave_qt_event_listener); connect (_octave_qt_event_listener, SIGNAL (current_directory_has_changed_signal (QString)), @@ -868,3 +889,70 @@ SLOT (handle_quit_debug_mode ())); } +void +main_window::save_workspace_callback (const std::string& file) +{ + Fsave (ovl (file)); +} + +void +main_window::load_workspace_callback (const std::string& file) +{ + Fload (ovl (file)); +} + +void +main_window::clear_workspace_callback (void) +{ + Fclear (); +} + +void +main_window::clear_history_callback (void) +{ + command_history::clear (); + + _history_dock_widget->reset_model (); +} + +void +main_window::change_directory_callback (const std::string& directory) +{ + Fcd (ovl (directory)); +} + +void +main_window::debug_continue_callback (void) +{ + Fdbcont (); +} + +void +main_window::debug_step_into_callback (void) +{ + Fdbstep (ovl ("in")); +} + +void +main_window::debug_step_over_callback (void) +{ + Fdbstep (); +} + +void +main_window::debug_step_out_callback (void) +{ + Fdbstep (ovl ("out")); +} + +void +main_window::debug_quit_callback (void) +{ + Fdbquit (); +} + +void +main_window::exit_callback (void) +{ + Fquit (); +}
--- a/libgui/src/main-window.h +++ b/libgui/src/main-window.h @@ -44,30 +44,24 @@ // Own includes #include "resource-manager.h" -#include "octave-link.h" #include "workspace-view.h" #include "history-dockwidget.h" #include "files-dockwidget.h" #include "terminal-dockwidget.h" #include "documentation-dockwidget.h" #include "octave-qt-event-listener.h" -#include "octave-event-observer.h" /** - * \class MainWindow - * - * Represents the main window. - */ -class main_window - : public QMainWindow, public octave_event_observer + * \class MainWindow + * + * Represents the main window. + */ +class main_window : public QMainWindow { -Q_OBJECT public: + Q_OBJECT public: main_window (QWidget * parent = 0); ~main_window (); - void event_accepted (octave_event *e); - void event_reject (octave_event *e); - QTerminal *get_terminal_view () { return _terminal; } history_dock_widget *get_history_dock_widget () { @@ -83,15 +77,15 @@ void settings_changed (); public slots: - void report_status_message (QString statusMessage); + void report_status_message (const QString& statusMessage); void handle_save_workspace_request (); void handle_load_workspace_request (); void handle_clear_workspace_request (); void handle_clear_history_request (); - void handle_command_double_clicked (QString command); + void handle_command_double_clicked (const QString& command); void new_file (); void open_file (); - void open_file (QString file_name); + void open_file (const QString& file_name); void open_bug_tracker_page (); void open_agora_page (); void open_octave_forge_page (); @@ -100,9 +94,9 @@ void notice_settings (); void prepare_for_quit (); void reset_windows (); - void current_working_directory_has_changed (QString directory); + void current_working_directory_has_changed (const QString& directory); void change_current_working_directory (); - void set_current_working_directory (QString directory); + void set_current_working_directory (const QString& directory); void current_working_directory_up (); void focus_command_window (); @@ -120,15 +114,38 @@ void debug_step_out (); void debug_quit (); + void read_settings (); + void write_settings (); + protected: void closeEvent (QCloseEvent * closeEvent); - void read_settings (); - void write_settings (); private: void construct (); void establish_octave_link (); + void save_workspace_callback (const std::string& file); + + void load_workspace_callback (const std::string& file); + + void clear_workspace_callback (void); + + void clear_history_callback (void); + + void change_directory_callback (const std::string& directory); + + void debug_continue_callback (void); + + void debug_step_into_callback (void); + + void debug_step_over_callback (void); + + void debug_step_out_callback (void); + + void debug_quit_callback (void); + + void exit_callback (void); + QTerminal * _terminal; file_editor_interface * _file_editor; QMenu * _debug_menu;
new file mode 100644 --- /dev/null +++ b/libgui/src/module.mk @@ -0,0 +1,160 @@ +EXTRA_DIST += \ + src/module.mk \ + src/resource.qrc \ + $(octave_gui_UI) \ + $(octave_gui_ICONS) + +octave_gui_ICONS = \ + src/icons/arrow_right.png \ + src/icons/artsbuilderexecute.png \ + src/icons/bookmark.png \ + src/icons/bp_next.png \ + src/icons/bp_prev.png \ + src/icons/bp_rm_all.png \ + src/icons/bp_toggle.png \ + src/icons/chat.png \ + src/icons/configure.png \ + src/icons/db_cont.png \ + src/icons/db_step_in.png \ + src/icons/db_step_out.png \ + src/icons/db_step.png \ + src/icons/db_stop.png \ + src/icons/editcopy.png \ + src/icons/editcut.png \ + src/icons/editpaste.png \ + src/icons/filenew.png \ + src/icons/fileopen.png \ + src/icons/filesaveas.png \ + src/icons/filesave.png \ + src/icons/find.png \ + src/icons/help_index.png \ + src/icons/icons_license \ + src/icons/jabber_protocol.png \ + src/icons/logo.png \ + src/icons/question.png \ + src/icons/redled.png \ + src/icons/redo.png \ + src/icons/search.png \ + src/icons/star.png \ + src/icons/stop.png \ + src/icons/terminal.png \ + src/icons/undo.png \ + src/icons/up.png \ + src/icons/zoom-in.png \ + src/icons/zoom-out.png + +octave_gui_MOC = \ + src/m-editor/moc-file-editor-interface.cc \ + src/m-editor/moc-file-editor-tab.cc \ + src/m-editor/moc-file-editor.cc \ + src/m-editor/moc-find-dialog.cc \ + src/m-editor/moc-lexer-octave-gui.cc \ + src/moc-documentation-dockwidget.cc \ + src/moc-files-dockwidget.cc \ + src/moc-history-dockwidget.cc \ + src/moc-main-window.cc \ + src/moc-octave-qt-event-listener.cc \ + src/moc-settings-dialog.cc \ + src/moc-terminal-dockwidget.cc \ + src/moc-welcome-wizard.cc \ + src/moc-workspace-model.cc \ + src/moc-workspace-view.cc \ + src/octave-adapter/moc-octave-main-thread.cc \ + src/qtinfo/moc-parser.cc \ + src/qtinfo/moc-webinfo.cc + +octave_gui_RC = src/qrc-resource.cc + +octave_gui_UI = \ + src/settings-dialog.ui \ + src/welcome-wizard.ui + +octave_gui_UI_H = $(patsubst src/%.ui, src/ui-%.h, $(octave_gui_UI)) + +BUILT_SOURCES += $(octave_gui_UI_H) + +noinst_HEADERS += \ + src/documentation-dockwidget.h \ + src/files-dockwidget.h \ + src/history-dockwidget.h \ + src/m-editor/file-editor-interface.h \ + src/m-editor/file-editor-tab.h \ + src/m-editor/file-editor.h \ + src/m-editor/find-dialog.h \ + src/m-editor/lexer-octave-gui.h \ + src/main-window.h \ + src/octave-adapter/octave-event-listener.h \ + src/octave-adapter/octave-link.h \ + src/octave-adapter/octave-main-thread.h \ + src/octave-gui.h \ + src/octave-qt-event-listener.h \ + src/qtinfo/parser.h \ + src/qtinfo/webinfo.h \ + src/resource-manager.h \ + src/settings-dialog.h \ + src/symbol-information.h \ + src/terminal-dockwidget.h \ + src/welcome-wizard.h \ + src/workspace-model.h \ + src/workspace-view.h + +src_libgui_src_la_SOURCES = \ + src/documentation-dockwidget.cc \ + src/files-dockwidget.cc \ + src/history-dockwidget.cc \ + src/m-editor/file-editor-tab.cc \ + src/m-editor/file-editor.cc \ + src/m-editor/find-dialog.cc \ + src/m-editor/lexer-octave-gui.cc \ + src/main-window.cc \ + src/octave-adapter/octave-link.cc \ + src/octave-adapter/octave-main-thread.cc \ + src/octave-gui.cc \ + src/octave-qt-event-listener.cc \ + src/qtinfo/parser.cc \ + src/qtinfo/webinfo.cc \ + src/resource-manager.cc \ + src/settings-dialog.cc \ + src/symbol-information.cc \ + src/terminal-dockwidget.cc \ + src/welcome-wizard.cc \ + src/workspace-model.cc \ + src/workspace-view.cc + +nodist_src_libgui_src_la_SOURCES = $(octave_gui_MOC) $(octave_gui_RC) + +src_libgui_src_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + @OCTGUI_DLL_DEFS@ \ + -I$(QT_INCDIR) \ + -I$(QT_INCDIR)/QtCore \ + -I$(QT_INCDIR)/QtGui \ + -I$(QT_INCDIR)/QtNetwork \ + -I$(srcdir)/qterminal/libqterminal \ + -Isrc -I$(srcdir)/src \ + -I$(srcdir)/src/m-editor \ + -I$(srcdir)/src/octave-adapter \ + -I$(srcdir)/src/qtinfo \ + -I$(top_srcdir)/liboctave/cruft/misc \ + -I$(top_srcdir)/liboctave/array \ + -I$(top_builddir)/liboctave/numeric -I$(top_srcdir)/liboctave/numeric \ + -I$(top_builddir)/liboctave/operators -I$(top_srcdir)/liboctave/operators \ + -I$(top_srcdir)/liboctave/system \ + -I$(top_srcdir)/liboctave/util \ + -I$(top_builddir)/libinterp -I$(top_srcdir)/libinterp \ + -I$(top_builddir)/libinterp/parse-tree -I$(top_srcdir)/libinterp/parse-tree \ + -I$(top_builddir)/libinterp/interp-core -I$(top_srcdir)/libinterp/interp-core \ + -I$(top_builddir)/libinterp/interpfcn -I$(top_srcdir)/libinterp/interpfcn \ + -I$(top_srcdir)/libinterp/octave-value + +src_libgui_src_la_CFLAGS = $(AM_CFLAGS) $(WARN_CFLAGS) + +src_libgui_src_la_CXXFLAGS = $(AM_CXXFLAGS) $(WARN_CXXFLAGS) + +noinst_LTLIBRARIES += src/libgui-src.la + +CLEANFILES += \ + $(octave_gui_MOC) \ + $(octave_gui_UI_H) \ + $(octave_gui_RC) +
--- a/libgui/src/octave-adapter/octave-event-listener.h +++ b/libgui/src/octave-adapter/octave-event-listener.h @@ -31,7 +31,9 @@ octave_event_listener () { } virtual ~octave_event_listener () { } - virtual void current_directory_has_changed (std::string directory) = 0; + virtual void + current_directory_has_changed (const std::string& directory) = 0; + virtual void about_to_exit () = 0; virtual void entered_debug_mode () = 0;
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event-observer.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid - -This file is part of Octave. - -Octave 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. - -Octave 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 Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifndef OCTAVEEVENTOBSERVER_H -#define OCTAVEEVENTOBSERVER_H - -class octave_event; - -/** - * \class octave_event_observer - * \brief Implements the observer part for the observer pattern. - */ -class octave_event_observer -{ - public: - octave_event_observer () { } - virtual ~octave_event_observer () { } - - /** - * This will be called when an event has been accepted. Operations - * in this routine will be processed in the octave thread. - */ - virtual void event_accepted (octave_event *e) = 0; - - /** - * This will be called when an event has been rejected. Operations - * in this routine will be processed in the octave thread. - */ - virtual void event_reject (octave_event *e) = 0; -}; - -#include "octave-event.h" - -#endif // OCTAVEEVENTOBSERVER_H
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid -Copyright (C) 2011-2012 John P. Swensen - -This file is part of Octave. - -Octave 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. - -Octave 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 Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string> - -#include "cmd-hist.h" -#include "oct-env.h" - -#include "debug.h" -#include "oct-obj.h" -#include "parse.h" -#include "symtab.h" -#include "toplev.h" - -#include "octave-event.h" - -#include <readline/readline.h> - -void -octave_event::call_octave_function (std::string name) -{ - call_octave_function (name, octave_value_list ()); -} - -void -octave_event::call_octave_function (std::string name, - const octave_value_list& args, - int nargout) -{ - try - { - feval (name, args, nargout); - } catch (...) { } // Ignore exceptions. Crashes without that. -} - -void -octave_event::finish_readline_event () const -{ - rl_line_buffer[0] = '\0'; - rl_point = rl_end = 0; - rl_done = 1; - //rl_forced_update_display (); -} - -bool -octave_clear_history_event::perform () -{ - int i; - while ((i = command_history::length ()) > 0) { - command_history::remove (i - 1); - } - return true; -} - -bool -octave_debug_step_into_event::perform () -{ - octave_value_list args; - args.append (octave_value ("in")); - call_octave_function ("dbstep", args); - finish_readline_event (); - return true; -} - -bool -octave_debug_step_out_event::perform () -{ - octave_value_list args; - args.append (octave_value ("out")); - call_octave_function ("dbstep", args); - finish_readline_event (); - return true; -} - - -bool -octave_exit_event::perform () -{ - clean_up_and_exit (0); - return true; -} - -bool -octave_run_file_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("run", args); - finish_readline_event (); - return true; -} - -bool -octave_change_directory_event::perform () -{ - return octave_env::chdir (_directory); -} - -bool -octave_load_workspace_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("load", args); - return true; -} - -bool -octave_save_workspace_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("save", args); - return true; -} - -bool -octave_add_breakpoint_event::perform () -{ - bp_table::intmap intmap; - intmap[0] = _line + 1; - - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - intmap = bp_table::add_breakpoint (_function_name, intmap); - octave_env::chdir (previous_directory); - return intmap.size () > 0; -} - -bool -octave_remove_breakpoint_event::perform () -{ - bp_table::intmap intmap; - intmap[0] = _line; - - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - bp_table::remove_breakpoint (_function_name, intmap); - octave_env::chdir (previous_directory); - return true; // TODO: Check result. -} - -bool -octave_remove_all_breakpoints_event::perform () -{ - bp_table::intmap intmap; - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - intmap = bp_table::remove_all_breakpoints_in_file (_function_name, true); - octave_env::chdir (previous_directory); - return intmap.size() > 0; -}
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid -Copyright (C) 2011-2012 John P. Swensen - -This file is part of Octave. - -Octave 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. - -Octave 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 Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifndef OCTAVEEVENT_H -#define OCTAVEEVENT_H - -#include <string> - -class octave_value_list; - -#include "octave-event-observer.h" - -/** - * \class octave_event - * \brief Base class for an octave event. - * In order to make communication with octave threadsafe, comunication is - * implemented via events. An application may create events and post them, - * however there is no guarantee events will be processed in a given time. - * - * In order to create an event, there must be an event observer. The event - * observer will be given the opportunity to react on the event as soon as - * it has been processed in the octave thread. Accepting and ignoring takes - * places in the octave thread. - */ -class octave_event -{ - public: - octave_event (octave_event_observer& o) - : _octave_event_observer (o) - { } - - virtual ~octave_event () - { } - - /** Performs what is necessary to make this event happen. This - * code is thread-safe since it will be executed in the octave - * thread. However, you should take care to keep this code as - * short as possible. */ - virtual bool perform () = 0; - - /** - * Accepts this event. This allows the event observer to react properly - * onto the event. - */ - void accept () - { _octave_event_observer.event_accepted (this); } - - /** - * Rejects this event. This allows the event observer to react properly - * onto the event. - */ - void reject () - { _octave_event_observer.event_reject (this); } - - protected: - void call_octave_function (std::string name); - - void call_octave_function (std::string name, - const octave_value_list& args, - int nargout = 0); - - void finish_readline_event () const; - - private: - octave_event_observer& _octave_event_observer; -}; - -class octave_update_history_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_update_history_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { return true; /* Always grant. */ } -}; - -class octave_update_workspace_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_update_workspace_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { return true; /* Always grant. */ } -}; - -/** Implements an octave exit event. */ -class octave_exit_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_exit_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform (); -}; - -/** Implements an octave run file event. */ -class octave_run_file_event : public octave_event -{ - public: - /** Creates a new octave_run_file_event. */ - octave_run_file_event (octave_event_observer& o, - std::string file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -/** Implements a change directory event. */ -class octave_change_directory_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_change_directory_event (octave_event_observer& o, - std::string directory) - : octave_event (o) - { _directory = directory; } - - bool perform (); - - private: - std::string _directory; -}; - -/** Implements a clear workspace event. */ -class octave_clear_workspace_event : public octave_event -{ - public: - /** Creates a new octave_run_file_event. */ - octave_clear_workspace_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { - call_octave_function ("clear"); - return true; - } -}; - -/** Implements a load workspace event. */ -class octave_load_workspace_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_load_workspace_event (octave_event_observer& o, - std::string file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -/** Implements a save workspace event. */ -class octave_save_workspace_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_save_workspace_event (octave_event_observer& o, - std::string file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -class octave_clear_history_event : public octave_event -{ - public: - /** Creates a new octave_clear_history_event. */ - octave_clear_history_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform (); -}; - -class octave_add_breakpoint_event : public octave_event -{ - public: - octave_add_breakpoint_event (octave_event_observer& o, - std::string path, - std::string function_name, - int line) - : octave_event (o) - { - _path = path; - _function_name = function_name; - _line = line; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - int get_line () - { - return _line; - } - - private: - std::string _path; - std::string _function_name; - int _line; -}; - -class octave_remove_breakpoint_event : public octave_event -{ - public: - octave_remove_breakpoint_event (octave_event_observer& o, - std::string path, - std::string function_name, - int line) - : octave_event (o) - { - _path = path; - _function_name = function_name; - _line = line; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - int get_line () - { - return _line; - } - - private: - std::string _path; - std::string _function_name; - int _line; -}; - -class octave_remove_all_breakpoints_event : public octave_event -{ - public: - octave_remove_all_breakpoints_event (octave_event_observer& o, - std::string path, - std::string function_name) - : octave_event (o) - { - _path = path; - _function_name = function_name; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - private: - std::string _path; - std::string _function_name; -}; - -class octave_debug_step_into_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_into_event. */ - octave_debug_step_into_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform (); -}; - -class octave_debug_step_over_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_over_event. */ - octave_debug_step_over_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbnext"); - finish_readline_event (); - return true; - } -}; - -class octave_debug_step_out_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_step_out_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform (); -}; - -class octave_debug_continue_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_continue_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbcont"); - finish_readline_event (); - return true; - } -}; - -class octave_debug_quit_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_quit_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbquit"); - finish_readline_event (); - return true; - } -}; - -#endif // OCTAVEEVENT_H
--- a/libgui/src/octave-adapter/octave-link.cc +++ b/libgui/src/octave-adapter/octave-link.cc @@ -28,140 +28,131 @@ #include "cmd-edit.h" #include "oct-env.h" #include "oct-mutex.h" +#include "singleton-cleanup.h" #include "symtab.h" #include "toplev.h" #include "octave-link.h" -int octave_readline_hook () +static int +octave_readline_hook (void) { - octave_link::instance ()->entered_readline_hook (); - octave_link::instance ()->generate_events (); - octave_link::instance ()->process_events (); - octave_link::instance ()->finished_readline_hook (); + octave_link::entered_readline_hook (); + octave_link::generate_events (); + octave_link::process_events (); + octave_link::finished_readline_hook (); + return 0; } -void octave_exit_hook (int status) +static void +octave_exit_hook (int) { - (void) status; - octave_link::instance ()->about_to_exit (); + octave_link::about_to_exit (); } -octave_link octave_link::_singleton; +octave_link *octave_link::instance = 0; -octave_link::octave_link () +octave_link::octave_link (void) + : event_listener (0), event_queue_mutex (new octave_mutex ()), + gui_event_queue (), last_cwd (), debugging (false) +{ } + +void +octave_link::do_launch_octave (void) { - _event_queue_mutex = new octave_mutex (); - _last_working_directory = ""; - _debugging_mode_active = false; -} + // Create both threads. + main_thread = new octave_main_thread (); + + command_editor::add_event_hook (octave_readline_hook); -octave_link::~octave_link () -{ + octave_exit = octave_exit_hook; + + // Start the first one. + main_thread->start (); } void -octave_link::launch_octave () +octave_link::do_register_event_listener (octave_event_listener *el) { - // Create both threads. - _octave_main_thread = new octave_main_thread (); - command_editor::add_event_hook (octave_readline_hook); - octave_exit = octave_exit_hook; - - // Start the first one. - _octave_main_thread->start (); + event_listener = el; } void -octave_link::register_event_listener (octave_event_listener *oel) -{ _octave_event_listener = oel; } - -void -octave_link::generate_events () +octave_link::do_generate_events (void) { std::string current_working_directory = octave_env::get_current_directory (); - if (current_working_directory != _last_working_directory) + + if (current_working_directory != last_cwd) { - _last_working_directory = current_working_directory; - if (_octave_event_listener) - _octave_event_listener - ->current_directory_has_changed (_last_working_directory); + last_cwd = current_working_directory; + + if (event_listener) + event_listener->current_directory_has_changed (last_cwd); } - if (_debugging_mode_active != Vdebugging) + if (debugging != Vdebugging) { - _debugging_mode_active = Vdebugging; - if (_octave_event_listener) + debugging = Vdebugging; + + if (event_listener) { - if (_debugging_mode_active) - _octave_event_listener->entered_debug_mode (); + if (debugging) + event_listener->entered_debug_mode (); else - _octave_event_listener->quit_debug_mode (); + event_listener->quit_debug_mode (); } } } void -octave_link::process_events () +octave_link::do_process_events (void) { - _event_queue_mutex->lock (); + event_queue_mutex->lock (); - while (_event_queue.size () > 0) - { - octave_event * e = _event_queue.front (); - _event_queue.pop (); - if (e->perform ()) - e->accept (); - else - e->reject (); - } - _event_queue_mutex->unlock (); -} + gui_event_queue.run (); -void -octave_link::post_event (octave_event *e) -{ - if (e) - { - _event_queue_mutex->lock (); - _event_queue.push (e); - _event_queue_mutex->unlock (); - } + event_queue_mutex->unlock (); } void -octave_link::event_accepted (octave_event *e) -{ delete e; } - -void -octave_link::event_reject (octave_event *e) -{ delete e; } - -void -octave_link::about_to_exit () +octave_link::do_about_to_exit (void) { - _event_queue_mutex->lock (); - while (!_event_queue.empty ()) - _event_queue.pop (); + event_queue_mutex->lock (); - _event_queue_mutex->unlock (); - - if (_octave_event_listener) - _octave_event_listener->about_to_exit (); -} + gui_event_queue.discard (); -void -octave_link::entered_readline_hook () -{ } + event_queue_mutex->unlock (); -void -octave_link::finished_readline_hook () -{ + if (event_listener) + event_listener->about_to_exit (); } std::string -octave_link::get_last_working_directory () +octave_link::do_last_working_directory (void) +{ + return last_cwd; +} + +bool +octave_link::instance_ok (void) { - return _last_working_directory; + bool retval = true; + + if (! instance) + { + instance = new octave_link (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); + } + + if (! instance) + { + ::error ("unable to create octave_link object!"); + + retval = false; + } + + return retval; }
--- a/libgui/src/octave-adapter/octave-link.h +++ b/libgui/src/octave-adapter/octave-link.h @@ -24,71 +24,162 @@ #ifndef OCTAVELINK_H #define OCTAVELINK_H -#include <queue> #include <string> class octave_mutex; +#include "event-queue.h" + #include "octave-main-thread.h" -#include "octave-event.h" -#include "octave-event-observer.h" #include "octave-event-listener.h" -/** - * \class OctaveLink - * \brief Provides threadsafe access to octave. - * \author Jacob Dawid - * This class is a wrapper around octave and provides threadsafety by - * buffering access operations to octave and executing them in the readline - * event hook, which lives in the octave thread. - */ -class octave_link : public octave_event_observer +// \class OctaveLink +// \brief Provides threadsafe access to octave. +// \author Jacob Dawid +// +// This class is a wrapper around octave and provides thread safety by +// buffering access operations to octave and executing them in the +// readline event hook, which lives in the octave thread. + +class octave_link { +protected: + + octave_link (void); + public: - /** Provides a way to access the unique octave_link object. */ - static octave_link * instance () { return &_singleton; } + + ~octave_link (void) { } + + static void launch_octave (void) + { + if (instance_ok ()) + instance->do_launch_octave (); + } + + static void register_event_listener (octave_event_listener *el) + { + if (instance_ok ()) + instance->do_register_event_listener (el); + } + + static void generate_events (void) + { + if (instance_ok ()) + instance->do_generate_events (); + } + + static void process_events (void) + { + if (instance_ok ()) + instance->do_process_events (); + } - /** Starts octave. */ - void launch_octave (); - void register_event_listener (octave_event_listener *oel); + template <class T> + static void post_event (T *obj, void (T::*method) (void)) + { + if (instance_ok ()) + instance->do_post_event (obj, method); + } + + template <class T, class A> + static void post_event (T *obj, void (T::*method) (A), A arg) + { + if (instance_ok ()) + instance->do_post_event (obj, method, arg); + } + + template <class T, class A> + static void post_event (T *obj, void (T::*method) (const A&), const A& arg) + { + if (instance_ok ()) + instance->do_post_event (obj, method, arg); + } - void generate_events (); - void process_events (); - void post_event (octave_event *e); - void event_accepted (octave_event *e); - void event_reject (octave_event *e); + static void about_to_exit (void) + { + if (instance_ok ()) + instance->do_about_to_exit (); + } + + static void entered_readline_hook (void) + { + if (instance_ok ()) + instance->do_entered_readline_hook (); + } - void about_to_exit (); + static void finished_readline_hook (void) + { + if (instance_ok ()) + instance->do_finished_readline_hook (); + } - void entered_readline_hook (); - void finished_readline_hook (); - - std::string get_last_working_directory (); + static std::string last_working_directory (void) + { + return instance_ok () + ? instance->do_last_working_directory () : std::string (); + } private: - /** Singleton. */ - octave_link (); - ~octave_link (); + + static octave_link *instance; + + static void cleanup_instance (void) { delete instance; instance = 0; } - octave_event_listener *_octave_event_listener; + // No copying! + + octave_link (const octave_link&); + + octave_link& operator = (const octave_link&); + + static bool instance_ok (void); - /** Thread running octave_main. */ - octave_main_thread *_octave_main_thread; + octave_event_listener *event_listener; + + // Thread running octave_main. + octave_main_thread *main_thread; + + // Semaphore to lock access to the event queue. + octave_mutex *event_queue_mutex; - /** Semaphore to lock access to the event queue. */ - octave_mutex *_event_queue_mutex; + // Event Queue. + event_queue gui_event_queue; + + // Stores the last known current working directory of octave. + std::string last_cwd; + + bool debugging; - /** Buffer for queueing events until they will be processed. */ - std::queue <octave_event *> _event_queue; + void do_launch_octave (void); + void do_register_event_listener (octave_event_listener *oel); + + void do_generate_events (void); + void do_process_events (void); - /** Stores the last known current working directory of octave. */ - std::string _last_working_directory; - bool _debugging_mode_active; + template <class T> + void do_post_event (T *obj, void (T::*method) (void)) + { + gui_event_queue.add_method (obj, method); + } - /** Semaphore to lock access to the performance information. */ - octave_mutex *_performance_information_mutex; + template <class T, class A> + void do_post_event (T *obj, void (T::*method) (A), A arg) + { + gui_event_queue.add_method (obj, method, arg); + } - /** Unique instance. Singelton! */ - static octave_link _singleton; + template <class T, class A> + void do_post_event (T *obj, void (T::*method) (const A&), const A& arg) + { + gui_event_queue.add_method (obj, method, arg); + } + + void do_about_to_exit (void); + + void do_entered_readline_hook (void) { } + void do_finished_readline_hook (void) { } + + std::string do_last_working_directory (void); }; + #endif // OCTAVELINK_H
--- a/libgui/src/octave-gui.cc +++ b/libgui/src/octave-gui.cc @@ -30,7 +30,8 @@ #include <iostream> -#include <syswait.h> +#include "lo-utils.h" +#include "syswait.h" #include "welcome-wizard.h" #include "resource-manager.h" @@ -69,7 +70,8 @@ waitpid (pid, &status, 0); - exit (WIFEXITED (status) ? WEXITSTATUS (status) : 127); + exit (octave_wait::ifexited (status) + ? octave_wait::exitstatus (status) : 127); } #endif @@ -80,6 +82,8 @@ { dissociate_terminal (); + setenv ("GNUTERM", "qt", 1); + QApplication application (argc, argv); while (true) @@ -106,6 +110,7 @@ resource_manager::update_network_settings (); main_window w; + w.read_settings (); // Get the widget settings after construction and before showing w.show (); w.focus_command_window ();
--- a/libgui/src/octave-gui.h +++ b/libgui/src/octave-gui.h @@ -23,6 +23,6 @@ #if !defined (octave_octave_gui_h) #define octave_octave_gui_h 1 -extern int octave_start_gui (int argc, char **argv); +extern OCTGUI_API int octave_start_gui (int argc, char **argv); #endif
--- a/libgui/src/octave-qt-event-listener.cc +++ b/libgui/src/octave-qt-event-listener.cc @@ -20,19 +20,23 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "octave-qt-event-listener.h" #include <QApplication> -octave_qt_event_listener::octave_qt_event_listener (QObject *parent) - : QObject (parent), octave_event_listener () +octave_qt_event_listener::octave_qt_event_listener (QObject *p) + : QObject (p), octave_event_listener () { } void -octave_qt_event_listener::current_directory_has_changed (std::string directory) +octave_qt_event_listener::current_directory_has_changed (const std::string& directory) { emit current_directory_has_changed_signal - (QString::fromStdString (directory)); + (QString::fromStdString (directory)); } void
--- a/libgui/src/octave-qt-event-listener.h +++ b/libgui/src/octave-qt-event-listener.h @@ -28,22 +28,22 @@ #include "octave-event-listener.h" class octave_qt_event_listener - : public QObject, public octave_event_listener + : public QObject, public octave_event_listener { - Q_OBJECT + Q_OBJECT public: - octave_qt_event_listener (QObject *parent = 0); + octave_qt_event_listener (QObject *parent = 0); - void current_directory_has_changed (std::string directory); - void about_to_exit (); + void current_directory_has_changed (const std::string& directory); + void about_to_exit (); - void entered_debug_mode (); - void quit_debug_mode (); + void entered_debug_mode (); + void quit_debug_mode (); - signals: - void current_directory_has_changed_signal (QString directory); - void entered_debug_mode_signal (); - void quit_debug_mode_signal (); +signals: + void current_directory_has_changed_signal (const QString& directory); + void entered_debug_mode_signal (); + void quit_debug_mode_signal (); }; #endif // OCTAVEQTEVENTLISTENER_H
--- a/libgui/src/qtinfo/parser.cc +++ b/libgui/src/qtinfo/parser.cc @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "parser.h" #include <QFileInfo> #include <QDir> @@ -26,8 +30,8 @@ #include <QProcess> #include <QBuffer> -parser::parser(QObject *parent) - : QObject(parent) +parser::parser(QObject *p) + : QObject(p) { _compressors_map.insert ("bz2", "bzip2 -dc \"%1\""); _compressors_map.insert ("gz", "gzip -dc \"%1\""); @@ -37,7 +41,7 @@ } void -parser::set_info_path (QString infoPath) +parser::set_info_path (const QString& infoPath) { this->_info_path = infoPath; @@ -96,7 +100,7 @@ } int -parser::is_ref (QString node) +parser::is_ref (const QString& node) { if (_ref_map.contains (node)) { @@ -108,8 +112,10 @@ } QString -parser::search_node (QString node) +parser::search_node (const QString& node_arg) { + QString node = node_arg; + QFileInfo file_info; QString ref; @@ -148,7 +154,7 @@ } QString -parser::search_node (QString node, QIODevice *io) +parser::search_node (const QString& node, QIODevice *io) { while (!io->atEnd ()) { @@ -182,7 +188,7 @@ } static QString -get_first_line (QString text) +get_first_line (const QString& text) { int n = text.indexOf ("\n"); @@ -196,7 +202,7 @@ } static QString -parser_node (QString text, QString node_name) +parser_node (const QString& text, const QString& node_name) { QString firstLine = get_first_line (text); QStringList nodes = firstLine.split (","); @@ -213,31 +219,31 @@ } QString -parser::get_node_name (QString text) +parser::get_node_name (const QString& text) { return parser_node (text, "Node:"); } QString -parser::get_node_up (QString text) +parser::get_node_up (const QString& text) { return parser_node (text, "Up:"); } QString -parser::get_node_next (QString text) +parser::get_node_next (const QString& text) { return parser_node (text, "Next:"); } QString -parser::get_node_prev (QString text) +parser::get_node_prev (const QString& text) { return parser_node (text, "Prev:"); } static void -replace_links (QString &text) +replace_links (QString& text) { QRegExp re ("(\\*[N|n]ote|\n\\*)([ |\n]+)([^:]+):([^:\\.,]*)([:,\\.])"); int i = 0, f; @@ -278,7 +284,7 @@ } static void -replace_colons (QString &text) +replace_colons (QString& text) { QRegExp re ("`([^']+)'"); int i = 0, f; @@ -294,7 +300,7 @@ } static void -info_to_html (QString &text) +info_to_html (QString& text) { text.replace ("&", "&"); text.replace ("<", "<"); @@ -307,8 +313,11 @@ } QString -parser::node_text_to_html (QString text, int anchorPos, QString anchor) +parser::node_text_to_html (const QString& text_arg, int anchorPos, + const QString& anchor) { + QString text = text_arg; + QString nodeName = get_node_name (text); QString nodeUp = get_node_up (text); QString nodeNext = get_node_next (text); @@ -475,7 +484,7 @@ } static void -replace (QString &text, QRegExp re, QString after) +replace (QString& text, const QRegExp& re, const QString& after) { int pos = 0; @@ -491,7 +500,7 @@ } QString -parser::global_search (QString text, int max_founds) +parser::global_search (const QString& text, int max_founds) { QString results; QStringList words = text.split (" ",QString::SkipEmptyParts);
--- a/libgui/src/qtinfo/parser.h +++ b/libgui/src/qtinfo/parser.h @@ -24,7 +24,7 @@ /** * \class parser - * This class gets nodes and searchs inside of `info files'. + * This class gets nodes and searchs inside of 'info files'. * <p>Each info file has nodes. Every node has the documentation. * Info files contains a map with position of each node.</p> * <p>What is position? @@ -45,20 +45,21 @@ public: parser (QObject *parent = 0); - void set_info_path (QString _info_path); + void set_info_path (const QString& _info_path); QString get_info_path (); - QString search_node (QString node); - QString global_search (QString text, int maxFounds); + QString search_node (const QString& node); + QString global_search (const QString& text, int maxFounds); /** Checks if this node is reference. If node is reference, it will be returned its position * in text, else it will be returned -1. */ - int is_ref (QString node); + int is_ref (const QString& node); /**Translates text of node to Html. If anchorPos is not -1, then anchor is inserted in that * position. */ - QString node_text_to_html (QString text, int anchorPos=-1, QString anchor=QString()); + QString node_text_to_html (const QString& text, int anchorPos = -1, + const QString& anchor = QString ()); private: struct node_position @@ -78,12 +79,12 @@ int real_size; }; - QString search_node (QString node, QIODevice * io); + QString search_node (const QString& node, QIODevice * io); QString get_next_node (QIODevice * io); - QString get_node_name (QString text); - QString get_node_up (QString text); - QString get_node_next (QString text); - QString get_node_prev (QString text); + QString get_node_name (const QString& text); + QString get_node_up (const QString& text); + QString get_node_next (const QString& text); + QString get_node_prev (const QString& text); /** Parses info files and gets map of node positions.*/ void parse_info_map();
--- a/libgui/src/qtinfo/webinfo.cc +++ b/libgui/src/qtinfo/webinfo.cc @@ -17,56 +17,66 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "webinfo.h" #include <QVBoxLayout> #include <QHBoxLayout> +#include "file-ops.h" +#include "help.h" +#include "defaults.h" -webinfo::webinfo (QWidget *parent) - :QWidget (parent) + +webinfo::webinfo (QWidget *p) + : QWidget (p) { _font_web = font (); - QVBoxLayout *layout = new QVBoxLayout (); - layout->setMargin (0); - setLayout (layout); + QVBoxLayout *vbox_layout = new QVBoxLayout (); + vbox_layout->setMargin (0); + setLayout (vbox_layout); - QHBoxLayout *hboxLayout = new QHBoxLayout (); - hboxLayout->setMargin (2); - layout->addLayout (hboxLayout); + QHBoxLayout *hbox_layout = new QHBoxLayout (); + hbox_layout->setMargin (2); + vbox_layout->addLayout (hbox_layout); _close_tab_button = new QPushButton (this); _close_tab_button->setSizePolicy (QSizePolicy::Fixed,QSizePolicy::Preferred); _close_tab_button->setIcon (QIcon (":/actions/icons/stop.png")); - hboxLayout->addWidget (_close_tab_button); + hbox_layout->addWidget (_close_tab_button); _tab_bar = new QTabBar (this); _tab_bar->setSizePolicy (QSizePolicy::Preferred,QSizePolicy::Preferred); _tab_bar->setExpanding (false); - hboxLayout->addWidget (_tab_bar); + hbox_layout->addWidget (_tab_bar); _zoom_in_button = new QToolButton (this); _zoom_in_button->setSizePolicy (QSizePolicy::Fixed,QSizePolicy::Preferred); _zoom_in_button->setIcon (QIcon (":/actions/icons/zoom-in.png")); - hboxLayout->addWidget (_zoom_in_button); + hbox_layout->addWidget (_zoom_in_button); _zoom_out_button = new QToolButton (this); _zoom_out_button->setSizePolicy (QSizePolicy::Fixed,QSizePolicy::Preferred); _zoom_out_button->setIcon (QIcon (":/actions/icons/zoom-out.png")); - hboxLayout->addWidget (_zoom_out_button); + hbox_layout->addWidget (_zoom_out_button); _stacked_widget = new QStackedWidget (this); - layout->addWidget (_stacked_widget); + vbox_layout->addWidget (_stacked_widget); - hboxLayout = new QHBoxLayout (); - layout->addLayout (hboxLayout); + hbox_layout = new QHBoxLayout (); + vbox_layout->addLayout (hbox_layout); _search_line_edit = new QLineEdit(this); +#ifdef HAVE_SETPLACEHOLDERTEXT _search_line_edit->setPlaceholderText (tr ("Type here and press \'Return\' to search")); - hboxLayout->addWidget (_search_line_edit); +#endif + hbox_layout->addWidget (_search_line_edit); _search_check_box = new QCheckBox (tr ("Global search")); - hboxLayout->addWidget (_search_check_box); + hbox_layout->addWidget (_search_check_box); connect (_close_tab_button, SIGNAL (clicked ()), this, SLOT (close_tab ())); connect (_tab_bar, SIGNAL (currentChanged (int)), this, SLOT (current_tab_changed (int))); @@ -76,18 +86,18 @@ resize (500, 300); - set_info_path ("../../doc/interpreter/octave.info"); + set_info_path (QString::fromStdString (Vinfo_file)); } void -webinfo::set_info_path (QString info_path) +webinfo::set_info_path (const QString& info_path) { _parser.set_info_path (info_path); load_node ("Top"); } void -webinfo::load_node (QString node_name) +webinfo::load_node (const QString& node_name) { //Check if node has been already opened. for (int i = 0;i < _tab_bar->count (); i++) @@ -120,8 +130,8 @@ void webinfo::current_tab_changed (int index) { - QVariant data = _tab_bar->tabData (index); - _text_browser = (QTextBrowser*) (data.value<void*> ()); + QVariant tab_data = _tab_bar->tabData (index); + _text_browser = static_cast<QTextBrowser*> (tab_data.value<void*> ()); _stacked_widget->setCurrentIndex (_stacked_widget->indexOf (_text_browser)); @@ -132,7 +142,7 @@ } QTextBrowser * -webinfo::addNewTab(QString name) +webinfo::addNewTab (const QString& name) { _text_browser = new QTextBrowser (this); _text_browser->setOpenLinks (false); @@ -146,9 +156,9 @@ int nt = _tab_bar->addTab (name); _tab_bar->setCurrentIndex (nt); - QVariant data; - data.setValue ( (void*)_text_browser); - _tab_bar->setTabData (nt, data); + QVariant tab_data; + tab_data.setValue (static_cast<void*> (_text_browser)); + _tab_bar->setTabData (nt, tab_data); connect (_tab_bar, SIGNAL (currentChanged (int)), this, SLOT (current_tab_changed (int))); @@ -170,8 +180,8 @@ void webinfo::closeTab (int index) { - QVariant data = _tab_bar->tabData (index); - QWidget *w = (QWidget*) (data.value<void*> ()); + QVariant tab_data = _tab_bar->tabData (index); + QWidget *w = static_cast<QWidget*> (tab_data.value<void*> ()); _stacked_widget->removeWidget (w); delete w;
--- a/libgui/src/qtinfo/webinfo.h +++ b/libgui/src/qtinfo/webinfo.h @@ -31,11 +31,11 @@ Q_OBJECT public: webinfo (QWidget *parent = 0); - void set_info_path (QString info_path); - void load_node (QString node_name); + void set_info_path (const QString& info_path); + void load_node (const QString& node_name); public slots: - void link_clicked (const QUrl &link); + void link_clicked (const QUrl& link); void current_tab_changed (int index); void close_tab (); void search (); @@ -55,6 +55,6 @@ parser _parser; QFont _font_web; - QTextBrowser *addNewTab (QString name); + QTextBrowser *addNewTab (const QString& name); void closeTab(int index); };
--- a/libgui/src/resource-manager.cc +++ b/libgui/src/resource-manager.cc @@ -53,7 +53,7 @@ } QString -resource_manager::find_translator_file (QString language) +resource_manager::find_translator_file (const QString& language) { // TODO: Quick hack to be able to test language files. return QString ("../languages/%1.qm").arg (language); @@ -114,20 +114,20 @@ QString settings_file = settings_path + "qt-settings"; if (!QFile::exists (settings_file)) - { - QDir("/").mkpath (settings_path); - QFile::copy (QString::fromStdString (default_qt_settings_file ()), - settings_file); - first_run = true; - } + { + QDir("/").mkpath (settings_path); + QFile::copy (QString::fromStdString (default_qt_settings_file ()), + settings_file); + first_run = true; + } else - first_run = false; + first_run = false; do_set_settings (settings_file); } void -resource_manager::do_set_settings (QString file) +resource_manager::do_set_settings (const QString& file) { delete settings; settings = new QSettings (file, QSettings::IniFormat); @@ -311,6 +311,7 @@ "__sort_rows_idx__ " "__strip_html_tags__ " "__token_count__ " + "__unimplemented__ " "__varval__ " "__version_info__ " "__voronoi__ " @@ -1638,7 +1639,6 @@ "unifinv " "unifpdf " "unifrnd " - "unimplemented " "union " "unique " "unix "
--- a/libgui/src/resource-manager.h +++ b/libgui/src/resource-manager.h @@ -54,13 +54,13 @@ instance->do_reload_settings (); } - static void set_settings (QString file) + static void set_settings (const QString& file) { if (instance_ok ()) instance->do_set_settings (file); } - static QString find_translator_file (QString language); + static QString find_translator_file (const QString& language); static void update_network_settings (void) { @@ -101,7 +101,7 @@ void do_reload_settings (void); - void do_set_settings (QString file); + void do_set_settings (const QString& file); void do_update_network_settings (void);
--- a/libgui/src/settings-dialog.cc +++ b/libgui/src/settings-dialog.cc @@ -20,13 +20,17 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "resource-manager.h" #include "settings-dialog.h" #include "ui-settings-dialog.h" #include <QSettings> -settings_dialog::settings_dialog (QWidget * parent): -QDialog (parent), ui (new Ui::settings_dialog) +settings_dialog::settings_dialog (QWidget *p): + QDialog (p), ui (new Ui::settings_dialog) { ui->setupUi (this); @@ -41,7 +45,8 @@ ui->editor_codeCompletion->setChecked (settings->value ("editor/codeCompletion",true).toBool () ); ui->editor_fontName->setCurrentFont (QFont (settings->value ("editor/fontName","Courier").toString()) ); ui->editor_fontSize->setValue (settings->value ("editor/fontSize",10).toInt ()); - ui->editor_longWindowTitle->setChecked (settings->value ("editor/longWindowTitle",true).toBool ()); + ui->editor_longWindowTitle->setChecked (settings->value ("editor/longWindowTitle",false).toBool ()); + ui->editor_restoreSession->setChecked (settings->value ("editor/restoreSession",true).toBool ()); ui->terminal_fontName->setCurrentFont (QFont (settings->value ("terminal/fontName","Courier").toString()) ); ui->terminal_fontSize->setValue (settings->value ("terminal/fontSize",10).toInt ()); ui->showFilenames->setChecked (settings->value ("showFilenames").toBool()); @@ -85,6 +90,12 @@ settings_dialog::~settings_dialog () { + delete ui; +} + +void +settings_dialog::write_changed_settings () +{ QSettings *settings = resource_manager::get_settings (); // FIXME -- what should happen if settings is 0? @@ -97,6 +108,7 @@ settings->setValue ("editor/fontName", ui->editor_fontName->currentFont().family()); settings->setValue ("editor/fontSize", ui->editor_fontSize->value()); settings->setValue ("editor/longWindowTitle", ui->editor_longWindowTitle->isChecked()); + settings->setValue ("editor/restoreSession", ui->editor_restoreSession->isChecked ()); settings->setValue ("terminal/fontSize", ui->terminal_fontSize->value()); settings->setValue ("terminal/fontName", ui->terminal_fontName->currentFont().family()); settings->setValue ("showFilenames", ui->showFilenames->isChecked ()); @@ -122,5 +134,4 @@ } settings->setValue ("terminal/cursorType", cursorType); settings->sync (); - delete ui; }
--- a/libgui/src/settings-dialog.h +++ b/libgui/src/settings-dialog.h @@ -32,9 +32,10 @@ class settings_dialog:public QDialog { -Q_OBJECT public: + Q_OBJECT public: explicit settings_dialog (QWidget * parent); ~settings_dialog (); + void write_changed_settings (); private: Ui::settings_dialog * ui;
--- a/libgui/src/settings-dialog.ui +++ b/libgui/src/settings-dialog.ui @@ -103,9 +103,6 @@ <property name="text"> <string>Show line numbers</string> </property> - <property name="checked"> - <bool>false</bool> - </property> </widget> </item> <item> @@ -116,9 +113,6 @@ <property name="text"> <string>Highlight current line</string> </property> - <property name="checked"> - <bool>false</bool> - </property> </widget> </item> <item> @@ -141,6 +135,13 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="editor_restoreSession"> + <property name="text"> + <string>Restore tabs from previous session on startup</string> + </property> + </widget> + </item> </layout> </item> <item> @@ -487,6 +488,13 @@ </widget> </widget> </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> </layout> </widget> <resources/> @@ -620,38 +628,6 @@ </hints> </connection> <connection> - <sender>editor_showLineNumbers</sender> - <signal>toggled(bool)</signal> - <receiver>editor_showLineNumbers</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>249</x> - <y>87</y> - </hint> - <hint type="destinationlabel"> - <x>249</x> - <y>87</y> - </hint> - </hints> - </connection> - <connection> - <sender>editor_highlightCurrentLine</sender> - <signal>toggled(bool)</signal> - <receiver>editor_highlightCurrentLine</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>249</x> - <y>112</y> - </hint> - <hint type="destinationlabel"> - <x>249</x> - <y>112</y> - </hint> - </hints> - </connection> - <connection> <sender>useProxyServer</sender> <signal>toggled(bool)</signal> <receiver>proxyUserName</receiver> @@ -700,18 +676,34 @@ </hints> </connection> <connection> - <sender>editor_codeCompletion</sender> - <signal>toggled(bool)</signal> - <receiver>editor_codeCompletion</receiver> - <slot>setEnabled(bool)</slot> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>settings_dialog</receiver> + <slot>accept()</slot> <hints> <hint type="sourcelabel"> - <x>249</x> - <y>137</y> + <x>299</x> + <y>366</y> </hint> <hint type="destinationlabel"> - <x>249</x> - <y>137</y> + <x>299</x> + <y>199</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>settings_dialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>299</x> + <y>366</y> + </hint> + <hint type="destinationlabel"> + <x>299</x> + <y>199</y> </hint> </hints> </connection>
--- a/libgui/src/symbol-information.cc +++ b/libgui/src/symbol-information.cc @@ -31,35 +31,49 @@ #include "symbol-information.h" -bool -symbol_information::from_symbol_record - (const symbol_table::symbol_record& symbol_record) +symbol_information::symbol_information (const symbol_table::symbol_record& sr) { - if (symbol_record.is_local () && !symbol_record.is_global () && !symbol_record.is_hidden ()) + if (sr.is_local () && !sr.is_global () && !sr.is_hidden ()) _scope = local; - else if (symbol_record.is_global ()) + else if (sr.is_global ()) _scope = global; - else if (symbol_record.is_persistent ()) + else if (sr.is_persistent ()) _scope = persistent; - else if (symbol_record.is_hidden ()) - _scope = hidden; + else + _scope = unknown; - _symbol = QString (symbol_record.name ().c_str ()); - _type = QString (symbol_record.varval ().type_name ().c_str ()); - octave_value ov = symbol_record.varval (); + _symbol = QString (sr.name ().c_str ()); + _class_name = QString (sr.varval ().class_name ().c_str ()); + octave_value ov = sr.varval (); + dim_vector dv = ov.dims (); // In case we have really large matrices or strings, cut them down // for performance reasons. QString short_value_string; bool use_short_value_string = false; - if (ov.is_matrix_type () || ov.is_cell ()) + if (ov.is_range ()) { - if (ov.rows () * ov.columns () > 10) - { - use_short_value_string = true; - short_value_string - = QString ("%1x%2 items").arg (ov.rows ()).arg (ov.columns ()); - } + use_short_value_string = true; + + Range r = ov.range_value (); + + double base = r.base (); + double increment = r.base (); + double limit = r.base (); + + std::stringstream buffer; + + buffer << base << ":"; + if (increment != 1 ) + buffer << increment << ":"; + buffer << limit; + + short_value_string = QString::fromStdString (buffer.str ()); + } + else if (ov.is_matrix_type () || ov.is_cell ()) + { + if (ov.numel () > 10) + use_short_value_string = true; } else if (ov.is_string ()) { @@ -83,23 +97,8 @@ } _value.replace("\n", " "); - if (ov.is_string ()) - _dimension = QString ("%1").arg (ov.string_value ().length ()); - else if (ov.is_range ()) - _dimension = QString ("%1 : %2 : %3").arg (ov.range_value ().base ()) - .arg (ov.range_value ().inc ()) - .arg (ov.range_value ().limit ()); - else if (ov.is_matrix_type () || ov.is_cell ()) - _dimension = QString ("%1x%2").arg (ov.rows ()) - .arg (ov.columns ()); - else if (ov.is_function_handle ()) - // See code for func2str for a possible solution - _dimension = QString ("func handle"); - else if (ov.is_inline_function ()) - // See code for formula for a possible solution - _dimension = QString ("inline func"); - else - _dimension = "1"; + _dimension = QString::fromStdString (dv.str ()); - return true; + _hash = _scope + qHash (_symbol) + qHash (_class_name) + qHash (_value) + + qHash (_dimension); }
--- a/libgui/src/symbol-information.h +++ b/libgui/src/symbol-information.h @@ -26,66 +26,89 @@ // FIXME -- we should not be including config.h in header files. #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif #include <QString> #include <QHash> -#include <sstream> - #include "symtab.h" /** - * \struct symbol_information - * \brief Meta-information over a symbol-table entry. - * \author Jacob Dawid - * This struct is used to store meta information over a symbol entry. - * It reduces memory consumption, since it only stores relevant data - * about a symbol-table entry that will be used in the model for the - * graphical user interface. - */ -struct symbol_information + * \struct symbol_information + * \brief Meta-information over a symbol-table entry. + * \author Jacob Dawid + * This struct is used to store meta information over a symbol entry. + * It reduces memory consumption, since it only stores relevant data + * about a symbol-table entry that will be used in the model for the + * graphical user interface. + */ +class symbol_information { +public: + enum Scope + { + unknown = 0, + local = 1, + global = 2, + persistent = 3 + }; + + symbol_information (const symbol_table::symbol_record& symbol_record); + + symbol_information (const symbol_information& x) + : _scope (x._scope), _symbol (x._symbol), _class_name (x._class_name), + _value (x._value), _dimension (x._dimension), _hash (x._hash) + { } + + symbol_information operator = (const symbol_information& x) { - local = 0, - global = 1, - persistent = 2, - hidden = 3 - }; + if (this != &x) + { + _scope = x._scope; + _symbol = x._symbol; + _class_name = x._class_name; + _value = x._value; + _dimension = x._dimension; + _hash = x._hash; + } + + return *this; + } + + ~symbol_information (void) { } + + QString symbol (void) const { return _symbol; } + QString class_name (void) const { return _class_name; } + QString value (void) const { return _value; } + QString dimension (void) const { return _dimension; } + Scope scope (void) const { return _scope; } + + friend bool + operator == (const symbol_information& a, const symbol_information& b) + { + return (a.hash () == b.hash () + && a.scope () == b.scope () + && a.symbol () == b.symbol () + && a.class_name () == b.class_name () + && a.value () == b.value () + && a.dimension () == b.dimension ()); + } + +private: + + // FIXME -- this is not really the scope of the symbol. + Scope _scope; QString _symbol; - QString _type; + QString _class_name; QString _value; QString _dimension; - Scope _scope; - - /** Hashes the symbol information for quickly comparing it. */ - int - hash () const - { - return qHash (_symbol) + qHash (_type) + qHash (_value) - + qHash (_dimension) + (int)_scope; - } - /** Compares two symbol information objects. */ - bool - equals (const symbol_information& other) const - { - if (hash () == other.hash ()) - { - return _symbol == other._symbol - && _type == other._type - && _value == other._value - && _scope == other._scope - && _dimension == other._dimension; - } - } + int _hash; - /** Extracts meta information from a given symbol record. */ - bool - from_symbol_record (const symbol_table::symbol_record& symbol_record); + int hash (void) const { return _hash; } }; #endif // SYMBOLINFORMATION_H
--- a/libgui/src/terminal-dockwidget.cc +++ b/libgui/src/terminal-dockwidget.cc @@ -20,14 +20,32 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "terminal-dockwidget.h" -terminal_dock_widget::terminal_dock_widget (QTerminal *terminal, QWidget *parent) - : QDockWidget (parent) +terminal_dock_widget::terminal_dock_widget (QTerminal *terminal, QWidget *p) + : QDockWidget (p) { setObjectName ("TerminalDockWidget"); + setWindowIcon (QIcon(":/actions/icons/logo.png")); setWindowTitle (tr ("Command Window")); setWidget (terminal); connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); } + +// slot for signal that is emitted when floating property changes +void +terminal_dock_widget::top_level_changed (bool floating) +{ + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlags hides it + } +}
--- a/libgui/src/terminal-dockwidget.h +++ b/libgui/src/terminal-dockwidget.h @@ -29,18 +29,20 @@ class terminal_dock_widget : public QDockWidget { Q_OBJECT -public: + public: terminal_dock_widget (QTerminal *terminal, QWidget *parent = 0); signals: - void active_changed (bool active); + void active_changed (bool active); public slots: - void handle_visibility_changed (bool visible) - { - if (visible) - emit active_changed (true); - } + void handle_visibility_changed (bool visible) + { + if (visible) + emit active_changed (true); + } + /** Slot when floating property changes */ + void top_level_changed (bool floating); }; #endif // TERMINALDOCKWIDGET_H
--- a/libgui/src/welcome-wizard.cc +++ b/libgui/src/welcome-wizard.cc @@ -20,12 +20,15 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "welcome-wizard.h" #include "ui-welcome-wizard.h" -welcome_wizard::welcome_wizard (QWidget *parent) : - QDialog (parent), - _ui (new Ui::welcome_wizard) +welcome_wizard::welcome_wizard (QWidget *p) + : QDialog (p), _ui (new Ui::welcome_wizard) { _ui->setupUi (this); connect (_ui->nextButton1, SIGNAL (clicked ()), this, SLOT (next ()));
--- a/libgui/src/welcome-wizard.h +++ b/libgui/src/welcome-wizard.h @@ -26,14 +26,14 @@ #include <QDialog> namespace Ui { - class welcome_wizard; + class welcome_wizard; } class welcome_wizard : public QDialog { Q_OBJECT -public: + public: explicit welcome_wizard (QWidget *parent = 0); ~welcome_wizard ();
--- a/libgui/src/workspace-model.cc +++ b/libgui/src/workspace-model.cc @@ -29,22 +29,22 @@ #include <list> -#include <symtab.h> +#include "symtab.h" +#include "variables.h" #include "workspace-model.h" #include "octave-link.h" -workspace_model::workspace_model(QObject *parent) - : QAbstractItemModel(parent), octave_event_observer () +workspace_model::workspace_model(QObject *p) + : QAbstractItemModel (p) { QList<QVariant> rootData; - rootData << tr ("Name") << tr ("Type") << tr("Dimension") << tr ("Value"); + rootData << tr ("Name") << tr ("Class") << tr("Dimension") << tr ("Value"); _rootItem = new tree_item(rootData); insert_top_level_item(0, new tree_item ("Local")); insert_top_level_item(1, new tree_item ("Global")); insert_top_level_item(2, new tree_item ("Persistent")); - insert_top_level_item(3, new tree_item ("Hidden")); connect(&_update_workspace_model_timer, SIGNAL (timeout ()), @@ -64,78 +64,21 @@ void workspace_model::request_update_workspace () { - octave_link::instance () - ->post_event (new octave_update_workspace_event (*this)); -} - -void -workspace_model::event_accepted (octave_event *e) -{ - if (dynamic_cast <octave_update_workspace_event*> (e)) - { - std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); - - _symbol_information.clear (); - for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); - iterator != symbolTable.end (); iterator++) - { - symbol_information symbolInformation; - symbolInformation.from_symbol_record (*iterator); - _symbol_information.push_back (symbolInformation); - } - - beginResetModel(); - top_level_item (0)->delete_child_items (); - top_level_item (1)->delete_child_items (); - top_level_item (2)->delete_child_items (); - top_level_item (3)->delete_child_items (); - - foreach (const symbol_information& s, _symbol_information) - { - tree_item *child = new tree_item (); - - child->set_data (0, s._symbol); - child->set_data (1, s._type); - child->set_data (2, s._dimension); - child->set_data (3, s._value); - - switch (s._scope) - { - case symbol_information::local: top_level_item (0)->add_child (child); break; - case symbol_information::global: top_level_item (1)->add_child (child); break; - case symbol_information::persistent: top_level_item (2)->add_child (child); break; - case symbol_information::hidden: top_level_item (3)->add_child (child); break; - } - } - - endResetModel(); - emit model_changed(); - } - - // Post a new event in a given time. - // This prevents flooding the event queue when no events are being processed. - _update_workspace_model_timer.start (); - delete e; -} - -void -workspace_model::event_reject (octave_event *e) -{ - delete e; + octave_link::post_event (this, &workspace_model::update_workspace_callback); } QModelIndex -workspace_model::index(int row, int column, const QModelIndex &parent) const +workspace_model::index(int row, int column, const QModelIndex &p) const { - if (!hasIndex(row, column, parent)) + if (!hasIndex(row, column, p)) return QModelIndex(); tree_item *parentItem; - if (!parent.isValid()) + if (!p.isValid()) parentItem = _rootItem; else - parentItem = static_cast<tree_item*>(parent.internalPointer()); + parentItem = static_cast<tree_item*>(p.internalPointer()); tree_item *childItem = parentItem->child(row); if (childItem) @@ -145,40 +88,46 @@ } QModelIndex -workspace_model::parent(const QModelIndex &index) const +workspace_model::parent(const QModelIndex &idx) const { - if (!index.isValid()) + if (!idx.isValid()) return QModelIndex(); - tree_item *childItem = static_cast<tree_item*>(index.internalPointer()); - tree_item *parentItem = childItem->parent(); + tree_item *childItem = static_cast<tree_item*>(idx.internalPointer()); + + if (childItem) + { + tree_item *parentItem = childItem->parent(); - if (parentItem == _rootItem) - return QModelIndex(); + if (! parentItem || parentItem == _rootItem) + return QModelIndex(); - return createIndex(parentItem->row(), 0, parentItem); + return createIndex(parentItem->row(), 0, parentItem); + } + else + return QModelIndex (); } int -workspace_model::rowCount(const QModelIndex &parent) const +workspace_model::rowCount(const QModelIndex &p) const { tree_item *parentItem; - if (parent.column() > 0) + if (p.column() > 0) return 0; - if (!parent.isValid()) + if (!p.isValid()) parentItem = _rootItem; else - parentItem = static_cast<tree_item*>(parent.internalPointer()); + parentItem = static_cast<tree_item*>(p.internalPointer()); return parentItem->child_count(); } int -workspace_model::columnCount(const QModelIndex &parent) const +workspace_model::columnCount(const QModelIndex &p) const { - if (parent.isValid()) - return static_cast<tree_item*>(parent.internalPointer())->column_count(); + if (p.isValid()) + return static_cast<tree_item*>(p.internalPointer())->column_count(); else return _rootItem->column_count(); } @@ -196,9 +145,9 @@ } Qt::ItemFlags -workspace_model::flags(const QModelIndex &index) const +workspace_model::flags(const QModelIndex &idx) const { - if (!index.isValid()) + if (!idx.isValid()) return 0; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; @@ -214,16 +163,67 @@ } QVariant -workspace_model::data(const QModelIndex &index, int role) const +workspace_model::data(const QModelIndex &idx, int role) const { - if (!index.isValid()) + if (!idx.isValid()) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); - tree_item *item = static_cast<tree_item*>(index.internalPointer()); + tree_item *item = static_cast<tree_item*>(idx.internalPointer()); - return item->data(index.column()); + return item->data(idx.column()); } +void +workspace_model::update_workspace_callback (void) +{ + std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); + + _symbol_information.clear (); + for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); + iterator != symbolTable.end (); iterator++) + _symbol_information.push_back (symbol_information (*iterator)); + + beginResetModel(); + top_level_item (0)->delete_child_items (); + top_level_item (1)->delete_child_items (); + top_level_item (2)->delete_child_items (); + + foreach (const symbol_information& s, _symbol_information) + { + tree_item *child = new tree_item (); + + child->set_data (0, s.symbol ()); + child->set_data (1, s.class_name ()); + child->set_data (2, s.dimension ()); + child->set_data (3, s.value ()); + + switch (s.scope ()) + { + case symbol_information::local: + top_level_item (0)->add_child (child); + break; + + case symbol_information::global: + top_level_item (1)->add_child (child); + break; + + case symbol_information::persistent: + top_level_item (2)->add_child (child); + break; + + default: + break; + } + } + + endResetModel(); + emit model_changed(); + + // Post a new event in a given time. + // This prevents flooding the event queue when no events are being processed. + _update_workspace_model_timer.start (); +} +
--- a/libgui/src/workspace-model.h +++ b/libgui/src/workspace-model.h @@ -30,25 +30,24 @@ #include <QTimer> #include "symbol-information.h" -#include "octave-event-observer.h" class tree_item { public: - tree_item (const QList<QVariant> &data, tree_item *parent = 0) { - _parent_item = parent; - _item_data = data; + tree_item (const QList<QVariant> &d, tree_item *p = 0) { + _parent_item = p; + _item_data = d; } - tree_item (QVariant data = QVariant(), tree_item *parent = 0) { + tree_item (QVariant d = QVariant(), tree_item *p = 0) { QList<QVariant> variantList; - variantList << data << QVariant () << QVariant () << QVariant (); - _parent_item = parent; + variantList << d << QVariant () << QVariant () << QVariant (); + _parent_item = p; _item_data = variantList; } ~tree_item () { - qDeleteAll (_child_items); + qDeleteAll (_child_items); } void insert_child_item (int at, tree_item *item) { @@ -62,8 +61,8 @@ } void delete_child_items () { - qDeleteAll (_child_items); - _child_items.clear (); + qDeleteAll (_child_items); + _child_items.clear (); } void remove_child (tree_item *item) { @@ -75,13 +74,13 @@ return _item_data[column]; } - void set_data (int column, QVariant data) + void set_data (int column, QVariant d) { - _item_data[column] = data; + _item_data[column] = d; } - tree_item *child (int row) { - return _child_items[row]; + tree_item *child (int r) { + return _child_items[r]; } int child_count () const { @@ -112,23 +111,20 @@ }; class workspace_model - : public QAbstractItemModel, public octave_event_observer + : public QAbstractItemModel { Q_OBJECT -public: + public: workspace_model (QObject *parent = 0); ~workspace_model (); - void event_accepted (octave_event *e); - void event_reject (octave_event *e); - QVariant data (const QModelIndex &index, int role) const; Qt::ItemFlags flags (const QModelIndex &index) const; QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index (int row, int column, - const QModelIndex &parent = QModelIndex ()) const; + const QModelIndex &parent = QModelIndex ()) const; QModelIndex parent (const QModelIndex &index) const; int rowCount (const QModelIndex &parent = QModelIndex ()) const; int columnCount (const QModelIndex &parent = QModelIndex ()) const; @@ -143,8 +139,11 @@ void model_changed (); private: + + void update_workspace_callback (void); + /** Timer for periodically updating the workspace model from the current - * symbol information. */ + * symbol information. */ QTimer _update_workspace_model_timer; /** Stores the current symbol information. */
--- a/libgui/src/workspace-view.cc +++ b/libgui/src/workspace-view.cc @@ -20,16 +20,22 @@ */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "workspace-view.h" #include "resource-manager.h" +#include <QHeaderView> #include <QHBoxLayout> #include <QVBoxLayout> #include <QPushButton> -workspace_view::workspace_view (QWidget * parent) : QDockWidget - (parent) +workspace_view::workspace_view (QWidget *p) + : QDockWidget (p) { setObjectName ("WorkspaceView"); + setWindowIcon (QIcon(":/actions/icons/logo.png")); setWindowTitle (tr ("Workspace")); // Create a new workspace model. @@ -47,12 +53,12 @@ setWidget (new QWidget (this)); // Create a new layout and add widgets to it. - QVBoxLayout *layout = new QVBoxLayout (); - layout->addWidget (_workspace_tree_view); - layout->setMargin (2); + QVBoxLayout *vbox_layout = new QVBoxLayout (); + vbox_layout->addWidget (_workspace_tree_view); + vbox_layout->setMargin (2); // Set the empty widget to have our layout. - widget ()->setLayout (layout); + widget ()->setLayout (vbox_layout); // Initialize collapse/expand state of the workspace subcategories. @@ -63,7 +69,10 @@ _explicit_collapse.local = settings->value ("workspaceview/local_collapsed", false).toBool (); _explicit_collapse.global = settings->value ("workspaceview/global_collapsed", false).toBool ();; _explicit_collapse.persistent = settings->value ("workspaceview/persistent_collapsed", false).toBool ();; - _explicit_collapse.hidden = settings->value ("workspaceview/hidden_collapsed", false).toBool ();; + + // Initialize column order and width of the workspace + + _workspace_tree_view->header ()->restoreState (settings->value("workspaceview/column_state").toByteArray ()); // Connect signals and slots. connect (this, SIGNAL (visibilityChanged (bool)), @@ -80,6 +89,9 @@ connect (_workspace_tree_view, SIGNAL (doubleClicked (QModelIndex)), this, SLOT (item_double_clicked (QModelIndex))); + // topLevelChanged is emitted when floating property changes (floating = true) + connect (this, SIGNAL (topLevelChanged(bool)), this, SLOT(top_level_changed(bool))); + } workspace_view::~workspace_view () @@ -91,7 +103,7 @@ settings->setValue("workspaceview/local_collapsed", _explicit_collapse.local); settings->setValue("workspaceview/global_collapsed", _explicit_collapse.global); settings->setValue("workspaceview/persistent_collapsed", _explicit_collapse.persistent); - settings->setValue("workspaceview/hidden_collapsed", _explicit_collapse.hidden); + settings->setValue("workspaceview/column_state", _workspace_tree_view->header ()->saveState ()); } void @@ -121,7 +133,6 @@ QModelIndex local_model_index = _workspace_model->index (0, 0); QModelIndex global_model_index = _workspace_model->index (1, 0); QModelIndex persistent_model_index = _workspace_model->index (2, 0); - QModelIndex hidden_model_index = _workspace_model->index (3, 0); if (_explicit_collapse.local) { _workspace_tree_view->collapse (local_model_index); @@ -140,12 +151,6 @@ } else { _workspace_tree_view->expand (persistent_model_index); } - - if (_explicit_collapse.hidden) { - _workspace_tree_view->collapse (hidden_model_index); - } else { - _workspace_tree_view->expand (hidden_model_index); - } } void @@ -165,7 +170,7 @@ // In order to make collapsing/expanding work again, we need to set // flags ourselves here. QMap<int, QVariant> item_data - = _workspace_model->itemData (index); + = _workspace_model->itemData (index); if (item_data[0] == "Local") _explicit_collapse.local = true; @@ -173,8 +178,6 @@ _explicit_collapse.global = true; if (item_data[0] == "Persistent") _explicit_collapse.persistent = true; - if (item_data[0] == "Hidden") - _explicit_collapse.hidden = true; } void @@ -194,7 +197,7 @@ // In order to make collapsing/expanding work again, we need to do set // flags ourselves here. QMap<int, QVariant> item_data - = _workspace_model->itemData (index); + = _workspace_model->itemData (index); if (item_data[0] == "Local") _explicit_collapse.local = false; @@ -202,20 +205,28 @@ _explicit_collapse.global = false; if (item_data[0] == "Persistent") _explicit_collapse.persistent = false; - if (item_data[0] == "Hidden") - _explicit_collapse.hidden = false; } void -workspace_view::item_double_clicked (QModelIndex index) +workspace_view::item_double_clicked (QModelIndex) { - Q_UNUSED (index); // TODO: Implement opening a dialog that allows the user to change a variable in the workspace. } void -workspace_view::closeEvent (QCloseEvent *event) +workspace_view::closeEvent (QCloseEvent *e) { emit active_changed (false); - QDockWidget::closeEvent (event); + QDockWidget::closeEvent (e); } + +// slot for signal that is emitted when floating property changes +void +workspace_view::top_level_changed (bool floating) +{ + if(floating) + { + setWindowFlags(Qt::Window); // make a window from the widget when floating + show(); // make it visible again since setWindowFlags hides it + } +}
--- a/libgui/src/workspace-view.h +++ b/libgui/src/workspace-view.h @@ -26,19 +26,21 @@ #include <QDockWidget> #include <QTreeView> #include <QSemaphore> -#include "octave-link.h" + #include "workspace-model.h" class workspace_view : public QDockWidget { Q_OBJECT -public: + public: workspace_view (QWidget * parent = 0); ~workspace_view (); public slots: void handle_visibility_changed (bool visible); void model_changed (); + /** Slot when floating property changes */ + void top_level_changed (bool floating); signals: /** Custom signal that tells if a user has clicke away that dock widget. */ @@ -63,7 +65,6 @@ bool local; bool global; bool persistent; - bool hidden; } _explicit_collapse; };
--- a/libinterp/Makefile.am +++ b/libinterp/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for Octave's src directory +# Makefile for Octave's libinterp directory # # Copyright (C) 1993-2012 John W. Eaton # @@ -24,8 +24,12 @@ ## Search local directories before those specified by the user. AM_CPPFLAGS = \ - -I$(top_srcdir)/libcruft/misc \ - -I../liboctave -I$(top_srcdir)/liboctave \ + -I$(top_srcdir)/liboctave/cruft/misc \ + -I$(top_srcdir)/liboctave/array \ + -I$(top_builddir)/liboctave/numeric -I$(top_srcdir)/liboctave/numeric \ + -I$(top_builddir)/liboctave/operators -I$(top_srcdir)/liboctave/operators \ + -I$(top_srcdir)/liboctave/system \ + -I$(top_srcdir)/liboctave/util \ -I$(srcdir)/octave-value \ -I$(srcdir)/operators \ -Iparse-tree -I$(srcdir)/parse-tree \ @@ -34,6 +38,10 @@ -Icorefcn \ -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu +AM_CFLAGS += $(WARN_CFLAGS) + +AM_CXXFLAGS += $(WARN_CXXFLAGS) + octlib_LTLIBRARIES = liboctinterp.la ## Order matters here. Leave builtins.cc last, because it depends on @@ -51,7 +59,7 @@ parse-tree/oct-parse.cc \ oct-conf.h \ version.h \ - $(BUILT_SOURCES_EXTRA) \ + builtin-defun-decls.h \ builtins.cc BUILT_DISTFILES = \ @@ -65,6 +73,7 @@ interp-core/oct-errno.cc \ interpfcn/defaults.h \ interpfcn/graphics.h \ + builtin-defun-decls.h \ operators/ops.cc \ oct-conf.h \ version.h \ @@ -92,13 +101,13 @@ interpfcn/graphics-props.cc \ parse-tree/oct-gperf.h \ builtins.h \ + builtin-defun-decls.h \ octave.h \ - $(OV_INCLUDES) \ - $(OV_SPARSE_INCLUDES) \ - $(PT_INCLUDES) \ - $(OPERATOR_INCLUDES) \ - $(INTERP_CORE_INCLUDES) \ - $(INTERPFCN_INCLUDES) + $(OCTAVE_VALUE_INC) \ + $(PARSE_TREE_INC) \ + $(OPERATORS_INC) \ + $(INTERP_CORE_INC) \ + $(INTERPFCN_INC) nodist_octinclude_HEADERS = \ interp-core/mxarray.h \ @@ -150,6 +159,7 @@ interpfcn/defaults.h \ interpfcn/graphics.h \ operators/ops.cc \ + builtin-defun-decls.h \ builtins.cc \ oct-conf.h \ version.h \ @@ -165,8 +175,7 @@ interp-core/libinterp-core.la \ interpfcn/libinterpfcn.la \ corefcn/libcorefcn.la \ - ../liboctave/liboctave.la \ - ../libcruft/libcruft.la \ + $(top_builddir)/liboctave/liboctave.la \ $(LIBOCTINTERP_LINK_DEPS) # Increment these as needed and according to the rules in the libtool manual: @@ -182,9 +191,6 @@ -bindir $(bindir) \ $(LIBOCTINTERP_LINK_OPTS) -## FIXME: Does this rule need to be uncommented? -#fft.df fft.lo fft2.df fft2.lo fftn.df fftn.lo: CPPFLAGS += $(FFTW_XCPPFLAGS) - ## Section for defining and creating DEF_FILES SRC_DEF_FILES := $(shell $(srcdir)/find-defun-files.sh "$(srcdir)" $(DIST_SRC)) @@ -204,6 +210,8 @@ $(DEF_FILES): $(OPT_HANDLERS) $(OPT_INC) +## FIXME: The following two variables are deprecated and should be removed +## in Octave version 3.12. DLL_CDEFS = @OCTINTERP_DLL_DEFS@ DLL_CXXDEFS = @OCTINTERP_DLL_DEFS@ @@ -223,9 +231,10 @@ ## Special rules: ## Mostly for sources which must be built before rest of compilation. -## oct-conf.h must depend on Makefile. Calling configure -## may change default/config values. However, calling configure will also -## regenerate the Makefiles from Makefile.am and trigger the rules below. +## oct-conf.h must depend on Makefile. +## Calling configure may change default/config values. +## However, calling configure will also regenerate the Makefiles from +## Makefile.am and trigger the rules below. oct-conf.h: oct-conf.in.h Makefile @$(do_subst_config_vals) @@ -240,7 +249,11 @@ mv $@-t $@ builtins.cc: $(DEF_FILES) mkbuiltins - $(srcdir)/mkbuiltins $(DEF_FILES) > $@-t + $(srcdir)/mkbuiltins --source $(DEF_FILES) > $@-t + mv $@-t $@ + +builtin-defun-decls.h: $(SRC_DEF_FILES) mkbuiltins + $(srcdir)/mkbuiltins --header $(SRC_DEF_FILES) > $@-t mv $@-t $@ if AMCOND_ENABLE_DYNAMIC_LINKING @@ -267,7 +280,11 @@ all-local: $(OCT_STAMP_FILES) $(DLDFCN_PKG_ADD_FILE) endif +if AMCOND_BUILD_DOCS +install-data-hook: install-oct install-built-in-docstrings +else install-data-hook: install-oct +endif uninstall-local: uninstall-oct @@ -301,6 +318,13 @@ endif .PHONY: install-oct uninstall-oct +if AMCOND_BUILD_DOCS +install-built-in-docstrings: + $(MKDIR_P) $(DESTDIR)$(octetcdir) + $(INSTALL_DATA) DOCSTRINGS $(DESTDIR)$(octetcdir)/built-in-docstrings +endif +.PHONY: install-built-in-docstrings + CLEANFILES = \ $(DLDFCN_PKG_ADD_FILE) \ interpfcn/graphics-props.cc \
--- a/libinterp/builtins.h +++ b/libinterp/builtins.h @@ -23,6 +23,10 @@ #if !defined (octave_builtins_h) #define octave_builtins_h 1 +#if !defined (MAKE_BUILTINS) +#include "builtin-defun-decls.h" +#endif + extern OCTINTERP_API void install_builtins (void); #endif
--- a/libinterp/corefcn/__qp__.cc +++ b/libinterp/corefcn/__qp__.cc @@ -51,7 +51,7 @@ DiagMatrix S = A_svd.singular_values (); - ColumnVector s = S.diag (); + ColumnVector s = S.extract_diag (); Matrix V = A_svd.right_singular_matrix ();
--- a/libinterp/corefcn/conv2.cc +++ b/libinterp/corefcn/conv2.cc @@ -88,6 +88,12 @@ shape = args(3).string_value (); } + if (args(0).ndims () > 2 || args(1).ndims () > 2) + { + error ("conv2: A and B must be 1-D vectors or 2-D matrices"); + return retval; + } + if (shape == "full") ct = convn_full; else if (shape == "same") @@ -101,125 +107,125 @@ return retval; } - if (separable) - { - // If user requests separable, check first two params are vectors + if (separable) + { + // If user requests separable, check first two params are vectors - if (! (1 == args(0).rows () || 1 == args(0).columns ()) - || ! (1 == args(1).rows () || 1 == args(1).columns ())) - { - print_usage (); - return retval; - } + if (! (1 == args(0).rows () || 1 == args(0).columns ()) + || ! (1 == args(1).rows () || 1 == args(1).columns ())) + { + print_usage (); + return retval; + } - if (args(0).is_single_type () || args(1).is_single_type () - || args(2).is_single_type ()) - { - if (args(0).is_complex_type () || args(1).is_complex_type () - || args(2).is_complex_type ()) - { - FloatComplexMatrix a (args(2).float_complex_matrix_value ()); - if (args(1).is_real_type () && args(2).is_real_type ()) - { - FloatColumnVector v1 (args(0).float_vector_value ()); - FloatRowVector v2 (args(1).float_vector_value ()); - retval = convn (a, v1, v2, ct); - } - else - { - FloatComplexColumnVector v1 (args(0).float_complex_vector_value ()); - FloatComplexRowVector v2 (args(1).float_complex_vector_value ()); - retval = convn (a, v1, v2, ct); - } - } - else - { - FloatColumnVector v1 (args(0).float_vector_value ()); - FloatRowVector v2 (args(1).float_vector_value ()); - FloatMatrix a (args(2).float_matrix_value ()); - retval = convn (a, v1, v2, ct); - } - } - else - { - if (args(0).is_complex_type () || args(1).is_complex_type () - || args(2).is_complex_type ()) - { - ComplexMatrix a (args(2).complex_matrix_value ()); - if (args(1).is_real_type () && args(2).is_real_type ()) - { - ColumnVector v1 (args(0).vector_value ()); - RowVector v2 (args(1).vector_value ()); - retval = convn (a, v1, v2, ct); - } - else - { - ComplexColumnVector v1 (args(0).complex_vector_value ()); - ComplexRowVector v2 (args(1).complex_vector_value ()); - retval = convn (a, v1, v2, ct); - } - } - else - { - ColumnVector v1 (args(0).vector_value ()); - RowVector v2 (args(1).vector_value ()); - Matrix a (args(2).matrix_value ()); - retval = convn (a, v1, v2, ct); - } - } - } // if (separable) - else - { - if (args(0).is_single_type () || args(1).is_single_type ()) - { - if (args(0).is_complex_type () || args(1).is_complex_type ()) - { - FloatComplexMatrix a (args(0).float_complex_matrix_value ()); - if (args(1).is_real_type ()) - { - FloatMatrix b (args(1).float_matrix_value ()); - retval = convn (a, b, ct); - } - else - { - FloatComplexMatrix b (args(1).float_complex_matrix_value ()); - retval = convn (a, b, ct); - } - } - else - { - FloatMatrix a (args(0).float_matrix_value ()); - FloatMatrix b (args(1).float_matrix_value ()); - retval = convn (a, b, ct); - } - } - else - { - if (args(0).is_complex_type () || args(1).is_complex_type ()) - { - ComplexMatrix a (args(0).complex_matrix_value ()); - if (args(1).is_real_type ()) - { - Matrix b (args(1).matrix_value ()); - retval = convn (a, b, ct); - } - else - { - ComplexMatrix b (args(1).complex_matrix_value ()); - retval = convn (a, b, ct); - } - } - else - { - Matrix a (args(0).matrix_value ()); - Matrix b (args(1).matrix_value ()); - retval = convn (a, b, ct); - } - } + if (args(0).is_single_type () || args(1).is_single_type () + || args(2).is_single_type ()) + { + if (args(0).is_complex_type () || args(1).is_complex_type () + || args(2).is_complex_type ()) + { + FloatComplexMatrix a (args(2).float_complex_matrix_value ()); + if (args(1).is_real_type () && args(2).is_real_type ()) + { + FloatColumnVector v1 (args(0).float_vector_value ()); + FloatRowVector v2 (args(1).float_vector_value ()); + retval = convn (a, v1, v2, ct); + } + else + { + FloatComplexColumnVector v1 (args(0).float_complex_vector_value ()); + FloatComplexRowVector v2 (args(1).float_complex_vector_value ()); + retval = convn (a, v1, v2, ct); + } + } + else + { + FloatColumnVector v1 (args(0).float_vector_value ()); + FloatRowVector v2 (args(1).float_vector_value ()); + FloatMatrix a (args(2).float_matrix_value ()); + retval = convn (a, v1, v2, ct); + } + } + else + { + if (args(0).is_complex_type () || args(1).is_complex_type () + || args(2).is_complex_type ()) + { + ComplexMatrix a (args(2).complex_matrix_value ()); + if (args(1).is_real_type () && args(2).is_real_type ()) + { + ColumnVector v1 (args(0).vector_value ()); + RowVector v2 (args(1).vector_value ()); + retval = convn (a, v1, v2, ct); + } + else + { + ComplexColumnVector v1 (args(0).complex_vector_value ()); + ComplexRowVector v2 (args(1).complex_vector_value ()); + retval = convn (a, v1, v2, ct); + } + } + else + { + ColumnVector v1 (args(0).vector_value ()); + RowVector v2 (args(1).vector_value ()); + Matrix a (args(2).matrix_value ()); + retval = convn (a, v1, v2, ct); + } + } + } // if (separable) + else + { + if (args(0).is_single_type () || args(1).is_single_type ()) + { + if (args(0).is_complex_type () || args(1).is_complex_type ()) + { + FloatComplexMatrix a (args(0).float_complex_matrix_value ()); + if (args(1).is_real_type ()) + { + FloatMatrix b (args(1).float_matrix_value ()); + retval = convn (a, b, ct); + } + else + { + FloatComplexMatrix b (args(1).float_complex_matrix_value ()); + retval = convn (a, b, ct); + } + } + else + { + FloatMatrix a (args(0).float_matrix_value ()); + FloatMatrix b (args(1).float_matrix_value ()); + retval = convn (a, b, ct); + } + } + else + { + if (args(0).is_complex_type () || args(1).is_complex_type ()) + { + ComplexMatrix a (args(0).complex_matrix_value ()); + if (args(1).is_real_type ()) + { + Matrix b (args(1).matrix_value ()); + retval = convn (a, b, ct); + } + else + { + ComplexMatrix b (args(1).complex_matrix_value ()); + retval = convn (a, b, ct); + } + } + else + { + Matrix a (args(0).matrix_value ()); + Matrix b (args(1).matrix_value ()); + retval = convn (a, b, ct); + } + } - } // if (separable) + } // if (separable) - return retval; + return retval; } /* @@ -277,6 +283,7 @@ %% Test input validation %!error conv2 () %!error conv2 (1) +%!error <must be 1-D vectors or 2-D matrices> conv2 (ones (2), ones (2,2,2)) %!error <SHAPE type not valid> conv2 (1,2, "NOT_A_SHAPE") %% Test alternate calling form which should be 2 vectors and a matrix %!error conv2 (ones (2), 1, 1) @@ -385,7 +392,7 @@ } } - return retval; + return retval; } /*
--- a/libinterp/corefcn/dlmread.cc +++ b/libinterp/corefcn/dlmread.cc @@ -221,7 +221,7 @@ if (! input_file) { - error ("dlmread: unable to open file `%s'", fname.c_str ()); + error ("dlmread: unable to open file '%s'", fname.c_str ()); return retval; } else
--- a/libinterp/corefcn/dot.cc +++ b/libinterp/corefcn/dot.cc @@ -215,7 +215,7 @@ { // Non-optimized evaluation. octave_value_list tmp; - tmp(1) = args(2); + tmp(1) = dim + 1; tmp(0) = do_binary_op (octave_value::op_el_mul, argx, argy); if (! error_state) { @@ -247,6 +247,19 @@ %!test %! x = [1+i, 3-i; 1-i, 3-i]; %! assert (dot (x, x), [4, 20]); + +%!test +%! x = int8 ([1 2]); +%! y = int8 ([2 3]); +%! assert (dot (x, y), 8); + +%!test +%! x = int8 ([1 2; 3 4]); +%! y = int8 ([5 6; 7 8]); +%! assert (dot (x, y), [26 44]); +%! assert (dot (x, y, 2), [17; 53]); +%! assert (dot (x, y, 3), [5 12; 21 32]); + */ DEFUN (blkmm, args, ,
--- a/libinterp/corefcn/mappers.cc +++ b/libinterp/corefcn/mappers.cc @@ -1754,6 +1754,12 @@ @end ifnottex\n\ \n\ For complex arguments, @code{sign} returns @code{x ./ abs (@var{x})}.\n\ +\n\ +Note that @code{sign (-0.0)} is 0.\n\ +Although IEEE 754 floating point\n\ +allows zero to be signed, 0.0 and -0.0 compare equal. If you must test\n\ +whether zero is signed, use the @code{signbit} function.\n\ +@seealso{signbit}\n\ @end deftypefn") { octave_value retval; @@ -1780,6 +1786,41 @@ %!error sign (1, 2) */ +DEFUNX ("signbit", Fsignbit, args, , + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} signbit (@var{x})\n\ +Return a nonzero value if the value of @var{x} has its sign bit set.\n\ +\n\ +This is not the same as @code{x < 0.0}, because IEEE 754 floating point\n\ +allows zero to be signed. The comparison @code{-0.0 < 0.0} is false,\n\ +but @code{signbit (-0.0)} will return a nonzero value.\n\ +@seealso{sign}\n\ +@end deftypefn") +{ + octave_value retval; + if (args.length () == 1) + retval = args(0).xsignbit (); + else + print_usage (); + + return retval; +} + +/* +%!assert (signbit (1) == 0) +%!assert (signbit (-2) != 0) +%!assert (signbit (0) == 0) +%!assert (signbit (-0) != 0) + +%!assert (signbit (single (1)) == 0) +%!assert (signbit (single (-2)) != 0) +%!assert (signbit (single (0)) == 0) +%!assert (signbit (single (-0)) != 0) + +%!error sign () +%!error sign (1, 2) +*/ + DEFUN (sin, args, , "-*- texinfo -*-\n\ @deftypefn {Mapping Function} {} sin (@var{x})\n\
--- a/libinterp/corefcn/mgorth.cc +++ b/libinterp/corefcn/mgorth.cc @@ -51,15 +51,16 @@ DEFUN (mgorth, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{y}, @var{h}] =} mgorth (@var{x}, @var{v})\n\ -Orthogonalize a given column vector @var{x} with respect to a given\n\ -orthonormal basis @var{v} using a modified Gram-Schmidt orthogonalization. \n\ +Orthogonalize a given column vector @var{x} with respect to a set of\n\ +orthonormal vectors comprising the columns of @var{v}\n\ +using the modified Gram-Schmidt method.\n\ On exit, @var{y} is a unit vector such that:\n\ \n\ @example\n\ @group\n\ norm (@var{y}) = 1\n\ @var{v}' * @var{y} = 0\n\ - @var{x} = @var{h}*[@var{v}, @var{y}]\n\ + @var{x} = [@var{v}, @var{y}]*@var{h}'\n\ @end group\n\ @end example\n\ \n\ @@ -81,7 +82,7 @@ if (arg_v.ndims () != 2 || arg_x.ndims () != 2 || arg_x.columns () != 1 || arg_v.rows () != arg_x.rows ()) { - error ("mgorth: V should me a matrix, and X a column vector with" + error ("mgorth: V should be a matrix, and X a column vector with" " the same number of rows as V."); return retval; }
--- a/libinterp/corefcn/module.mk +++ b/libinterp/corefcn/module.mk @@ -11,18 +11,18 @@ corefcn/Quad-opts.cc OPT_INC = \ - $(top_builddir)/liboctave/DASPK-opts.h \ - $(top_builddir)/liboctave/DASRT-opts.h \ - $(top_builddir)/liboctave/DASSL-opts.h \ - $(top_builddir)/liboctave/LSODE-opts.h \ - $(top_builddir)/liboctave/Quad-opts.h + $(top_builddir)/liboctave/numeric/DASPK-opts.h \ + $(top_builddir)/liboctave/numeric/DASRT-opts.h \ + $(top_builddir)/liboctave/numeric/DASSL-opts.h \ + $(top_builddir)/liboctave/numeric/LSODE-opts.h \ + $(top_builddir)/liboctave/numeric/Quad-opts.h -$(OPT_HANDLERS): corefcn/%.cc : $(top_builddir)/liboctave/%.in +$(OPT_HANDLERS): corefcn/%.cc : $(top_builddir)/liboctave/numeric/%.in $(PERL) $(top_srcdir)/build-aux/mk-opts.pl --opt-handler-fcns $< > $@-t mv $@-t $@ $(OPT_INC) : %.h : %.in - $(MAKE) -C $(top_builddir)/liboctave $(@F) + $(MAKE) -C $(top_builddir)/liboctave/numeric $(@F) COREFCN_SRC = \ corefcn/__contourc__.cc \ @@ -95,4 +95,5 @@ noinst_LTLIBRARIES += corefcn/libcorefcn.la corefcn_libcorefcn_la_SOURCES = $(COREFCN_SRC) +corefcn_libcorefcn_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS) $(FFTW_XCPPFLAGS)
--- a/libinterp/corefcn/quadcc.cc +++ b/libinterp/corefcn/quadcc.cc @@ -1720,7 +1720,7 @@ Vinvfx (iv->fx, &(iv->c[idx[2]]), 2); Vinvfx (iv->fx, &(iv->c[0]), 0); for (i = 0; i < nnans; i++) - iv->fx[i] = octave_NaN; + iv->fx[nans[i]] = octave_NaN; iv->a = iivals[j]; iv->b = iivals[j + 1]; iv->depth = 3; @@ -1849,7 +1849,7 @@ { downdate (&(iv->c[idx[d]]), n[d], d, nans, nnans); for (i = 0; i < nnans; i++) - iv->fx[i] = octave_NaN; + iv->fx[nans[i]] = octave_NaN; } /* Compute the error estimate. */ @@ -1994,7 +1994,7 @@ { downdate (ivl->c, n[0], 0, nans, nnans); for (i = 0; i < nnans; i++) - ivl->fx[i] = octave_NaN; + ivl->fx[nans[i]] = octave_NaN; } for (i = 0; i <= n[d]; i++) { @@ -2090,7 +2090,7 @@ { downdate (ivr->c, n[0], 0, nans, nnans); for (i = 0; i < nnans; i++) - ivr->fx[i] = octave_NaN; + ivr->fx[nans[i]] = octave_NaN; } for (i = 0; i <= n[d]; i++) { @@ -2255,6 +2255,19 @@ %!assert (quadcc (@(x) exp (-x .^ 2), -Inf, Inf), sqrt (pi), 1e-6) %!assert (quadcc (@(x) exp (-x .^ 2), -Inf, 0), sqrt (pi)/2, 1e-6) +## Test function with NaNs in interval +%!function y = __nansin (x) +%! nan_locs = [-3*pi/4, -pi/4, 0, pi/3, pi/2, pi]; +%! y = sin (x); +%! idx = min (abs (bsxfun (@minus, x(:), nan_locs)), [], 2); +%! y(idx < 1e-10) = NaN; +%!endfunction + +%!test +%! [q, err, npoints] = quadcc ("__nansin", -pi, pi); +%! assert (q, 0, eps); +%! assert (err, 0, 15*eps); + %% Test input validation %!error (quadcc ()) %!error (quadcc (@sin))
--- a/libinterp/corefcn/rcond.cc +++ b/libinterp/corefcn/rcond.cc @@ -91,4 +91,13 @@ %!assert (rcond (ones (2)), 0) %!assert (rcond ([1 1; 2 1]), 1/9) %!assert (rcond (magic (4)), 0, eps) + +%!shared x, sx +%! x = [-5.25, -2.25; -2.25, 1] * eps () + ones (2) / 2; +%! sx = [-5.25, -2.25; -2.25, 1] * eps ("single") + ones (2) / 2; +%!assert (rcond (x) < eps ()); +%!assert (rcond (sx) < eps ('single')); +%!assert (rcond (x*i) < eps ()); +%!assert (rcond (sx*i) < eps ('single')); + */
--- a/libinterp/corefcn/regexp.cc +++ b/libinterp/corefcn/regexp.cc @@ -45,12 +45,12 @@ #include "utils.h" // Replace backslash escapes in a string with the real values. We need -// this special function instead of the one in utils.cc because the set -// of escape sequences used in regexps is different from those used in -// the *printf functions. +// two special functions instead of the one in utils.cc because the set +// of escape sequences used for regexp patterns and replacement strings +// is different from those used in the *printf functions. static std::string -do_regexp_string_escapes (const std::string& s) +do_regexp_ptn_string_escapes (const std::string& s) { std::string retval; @@ -66,11 +66,56 @@ { switch (s[++j]) { - case '$': - retval[i] = '$'; + case 'b': // backspace + retval[i] = '\b'; break; - case 'a': +#if 0 +// FIXME : To be complete, we need to handle \oN, \o{N}. +// The PCRE library already handles \N where N +// is an octal number. New code needs to merely +// replace \oN or \o{N} with \N. + case 'o': // octal number +#endif + + default: // pass escape sequence through + retval[i] = '\\'; + retval[++i] = s[j]; + break; + } + } + else + { + retval[i] = s[j]; + } + + i++; + j++; + } + + retval.resize (i); + + return retval; +} + +static std::string +do_regexp_rep_string_escapes (const std::string& s) +{ + std::string retval; + + size_t i = 0; + size_t j = 0; + size_t len = s.length (); + + retval.resize (len); + + while (j < len) + { + if (s[j] == '\\' && j+1 < len) + { + switch (s[++j]) + { + case 'a': // alarm retval[i] = '\a'; break; @@ -98,10 +143,6 @@ retval[i] = '\v'; break; - case '\\': // backslash - retval[i] = '\\'; - break; - #if 0 // FIXME -- to be complete, we need to handle \oN, \o{N}, \xN, and // \x{N}. Hex digits may be upper or lower case. Brackets are @@ -110,8 +151,8 @@ case 'o': // octal number case 'x': // hex number #endif - - default: + + default: // pass escape sequence through retval[i] = '\\'; retval[++i] = s[j]; break; @@ -205,7 +246,7 @@ return retval; // Matlab compatibility. if (args(1).is_sq_string ()) - pattern = do_regexp_string_escapes (pattern); + pattern = do_regexp_ptn_string_escapes (pattern); regexp::opts options; options.case_insensitive (case_insensitive); @@ -1196,14 +1237,14 @@ return retval; // Matlab compatibility. if (args(1).is_sq_string ()) - pattern = do_regexp_string_escapes (pattern); + pattern = do_regexp_ptn_string_escapes (pattern); std::string replacement = args(2).string_value (); if (error_state) return retval; // Matlab compatibility. if (args(2).is_sq_string ()) - replacement = do_regexp_string_escapes (replacement); + replacement = do_regexp_rep_string_escapes (replacement); // Pack options excluding 'tokenize' and various output // reordering strings into regexp arg list
--- a/libinterp/corefcn/schur.cc +++ b/libinterp/corefcn/schur.cc @@ -169,7 +169,7 @@ if (ord_char != 'U' && ord_char != 'A' && ord_char != 'D' && ord_char != 'u' && ord_char != 'a' && ord_char != 'd') { - warning ("schur: incorrect ordered schur argument `%c'", + warning ("schur: incorrect ordered schur argument '%c'", ord.c_str ()); return retval; }
--- a/libinterp/corefcn/svd.cc +++ b/libinterp/corefcn/svd.cc @@ -216,7 +216,7 @@ if (nargout == 0 || nargout == 1) { - retval(0) = sigma.diag (); + retval(0) = sigma.extract_diag (); } else { @@ -244,7 +244,7 @@ if (nargout == 0 || nargout == 1) { - retval(0) = sigma.diag (); + retval(0) = sigma.extract_diag (); } else { @@ -275,7 +275,7 @@ if (nargout == 0 || nargout == 1) { - retval(0) = sigma.diag (); + retval(0) = sigma.extract_diag (); } else { @@ -303,7 +303,7 @@ if (nargout == 0 || nargout == 1) { - retval(0) = sigma.diag (); + retval(0) = sigma.extract_diag (); } else {
--- a/libinterp/corefcn/typecast.cc +++ b/libinterp/corefcn/typecast.cc @@ -25,6 +25,8 @@ #include <config.h> #endif +#include <climits> + #include "mx-base.h" #include "defun.h" @@ -130,7 +132,7 @@ @group\n\ @var{x} = uint16 ([1, 65535]);\n\ typecast (@var{x}, \"uint8\")\n\ - @result{} [ 0, 1, 255, 255]\n\ +@result{} [ 1, 0, 255, 255]\n\ @end group\n\ @end example\n\ @seealso{cast, bitunpack, bitpack, swapbytes}\n\
--- a/libinterp/dldfcn/__fltk_uigetfile__.cc +++ b/libinterp/dldfcn/__fltk_uigetfile__.cc @@ -24,7 +24,7 @@ #include <config.h> #endif -#if defined (HAVE_FLTK) +#ifdef HAVE_FLTK #ifdef WIN32 #define WIN32_LEAN_AND_MEAN @@ -39,6 +39,8 @@ // headers which may require Octave's Complex typedef. #undef Complex +#endif + #include "defun-dld.h" #include "file-ops.h" @@ -48,6 +50,7 @@ Undocumented internal function.\n\ @end deftypefn") { +#ifdef HAVE_FLTK // Expected argument list: // // args(0) ... FileFilter in fltk format @@ -132,6 +135,10 @@ Fl::flush (); return retval; +#else + error ("__fltk_uigetfile__: not available without OpenGL and FLTK libraries"); + return octave_value (); +#endif } /* @@ -139,4 +146,3 @@ %!assert (1) */ -#endif
--- a/libinterp/dldfcn/__init_fltk__.cc +++ b/libinterp/dldfcn/__init_fltk__.cc @@ -29,7 +29,7 @@ */ -// PKG_ADD: register_graphics_toolkit ("fltk"); +// PKG_ADD: if (__have_fltk__ ()) register_graphics_toolkit ("fltk"); endif #ifdef HAVE_CONFIG_H #include <config.h> @@ -38,7 +38,7 @@ #include "defun-dld.h" #include "error.h" -#if defined (HAVE_FLTK) +#ifdef HAVE_FLTK #include <map> #include <set> @@ -1984,10 +1984,17 @@ } }; +#endif + // Initialize the fltk graphics toolkit. -DEFUN_DLD (__init_fltk__, , , "") +DEFUN_DLD (__init_fltk__, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __init_fltk__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") { +#ifdef HAVE_FLTK if (! toolkit_loaded) { mlock (); @@ -2000,20 +2007,36 @@ args(0) = "__fltk_redraw__"; feval ("add_input_event_hook", args, 0); } - - octave_value retval; - return retval; -} - -DEFUN_DLD (__fltk_redraw__, , , "") -{ - __fltk_redraw__ (); +#else + error ("__init_fltk__: not available without OpenGL and FLTK libraries"); +#endif return octave_value (); } -DEFUN_DLD (__fltk_maxtime__, args, ,"") +DEFUN_DLD (__fltk_redraw__, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __fltk_redraw__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") { +#ifdef HAVE_FLTK + __fltk_redraw__ (); +#else + error ("__fltk_redraw__: not available without OpenGL and FLTK libraries"); +#endif + + return octave_value (); +} + +DEFUN_DLD (__fltk_maxtime__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{maxtime} =} __fltk_maxtime__ ()\n\ +@deftypefnx {Loadable Function} {} __fltk_maxtime__ (@var{maxtime})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ +#ifdef HAVE_FLTK octave_value retval = fltk_maxtime; if (args.length () == 1) @@ -2025,10 +2048,29 @@ } return retval; +#else + error ("__fltk_maxtime__: not available without OpenGL and FLTK libraries"); + return octave_value (); +#endif } +DEFUN_DLD (__have_fltk__, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{FLTK_available} =} __have_fltk__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + +#ifdef HAVE_FLTK + retval = true; +#else + retval = false; #endif + return retval; +} + // FIXME -- This function should be abstracted and made potentially // available to all graphics toolkits. This suggests putting it in // graphics.cc as is done for drawnow() and having the master @@ -2046,7 +2088,7 @@ @seealso{gui_mode}\n\ @end deftypefn") { -#if defined (HAVE_FLTK) +#ifdef HAVE_FLTK octave_value retval = wheel_zoom_speed; if (args.length () == 1) @@ -2086,7 +2128,7 @@ @seealso{mouse_wheel_zoom}\n\ @end deftypefn") { -#if defined (HAVE_FLTK) +#ifdef HAVE_FLTK caseless_str mode_str; if (gui_mode == pan_zoom) @@ -2122,8 +2164,7 @@ return octave_value (mode_str); #else - error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries"); + error ("gui_mode: not available without OpenGL and FLTK libraries"); return octave_value (); #endif } -
--- a/libinterp/dldfcn/__init_gnuplot__.cc +++ b/libinterp/dldfcn/__init_gnuplot__.cc @@ -33,6 +33,7 @@ #include <config.h> #endif +#include "builtins.h" #include "defun-dld.h" #include "error.h" #include "graphics.h" @@ -148,24 +149,17 @@ if (! error_state) { - args(1) = "\nquit;\n"; - args(0) = fids(0); - feval ("fputs", args); + Ffputs (ovl (fids(0), "\nquit;\n")); - args.resize (1); - feval ("fflush", args); - feval ("pclose", args); + Ffflush (ovl (fids(0))); + Fpclose (ovl (fids(0))); if (fids.numel () > 1) { - args(0) = fids(1); - feval ("pclose", args); + Fpclose (ovl (fids(1))); if (fids.numel () > 2) - { - args(0) = fids(2); - feval ("waitpid", args); - } + Fwaitpid (ovl (fids(2))); } } }
--- a/libinterp/dldfcn/__magick_read__.cc +++ b/libinterp/dldfcn/__magick_read__.cc @@ -381,7 +381,7 @@ if (! initialized) { - // Save the locale as GraphicsMagick might change this (depending on version) + // Save locale as GraphicsMagick might change this (depending on version) const char *static_locale = setlocale (LC_ALL, NULL); const std::string locale (static_locale); @@ -1080,7 +1080,7 @@ { std::string msg = fs.error (); - error ("imfinfo: error reading `%s': %s", + error ("imfinfo: error reading '%s': %s", filename.c_str (), msg.c_str ()); return retval;
--- a/libinterp/dldfcn/chol.cc +++ b/libinterp/dldfcn/chol.cc @@ -180,7 +180,6 @@ octave_idx_type nr = arg.rows (); octave_idx_type nc = arg.columns (); - bool natural = (nargout != 3); int arg_is_empty = empty_arg ("chol", nr, nc); @@ -191,14 +190,18 @@ if (arg.is_sparse_type ()) { + octave_idx_type info; + bool natural = (nargout != 3); + bool force = nargout > 1; + if (arg.is_real_type ()) { SparseMatrix m = arg.sparse_matrix_value (); if (! error_state) { - octave_idx_type info = nargout; - SparseCHOL fact (m, info, natural); + SparseCHOL fact (m, info, natural, force); + if (nargout == 3) { if (vecout) @@ -225,8 +228,7 @@ if (! error_state) { - octave_idx_type info = nargout; - SparseComplexCHOL fact (m, info, natural); + SparseComplexCHOL fact (m, info, natural, force); if (nargout == 3) { @@ -405,14 +407,16 @@ { if (arg.is_sparse_type ()) { + octave_idx_type info; + if (arg.is_real_type ()) { SparseMatrix m = arg.sparse_matrix_value (); if (! error_state) { - octave_idx_type info; SparseCHOL chol (m, info); + if (info == 0) retval = chol.inverse (); else @@ -425,8 +429,8 @@ if (! error_state) { - octave_idx_type info; SparseComplexCHOL chol (m, info); + if (info == 0) retval = chol.inverse (); else
--- a/libinterp/dldfcn/config-module.awk +++ b/libinterp/dldfcn/config-module.awk @@ -71,7 +71,7 @@ } printf ("dldfcn_%s_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED_LDFLAG) %s $(OCT_LINK_OPTS)\n", basename, ldflags[i]); - printf ("dldfcn_%s_la_LIBADD = $(DLD_LIBOCTINTERP_LIBADD) ../liboctave/liboctave.la ../libcruft/libcruft.la %s $(OCT_LINK_DEPS)\n", + printf ("dldfcn_%s_la_LIBADD = $(DLD_LIBOCTINTERP_LIBADD) ../liboctave/liboctave.la %s $(OCT_LINK_DEPS)\n", basename, libraries[i]); } }
--- a/libinterp/dldfcn/urlwrite.cc +++ b/libinterp/dldfcn/urlwrite.cc @@ -55,11 +55,6 @@ #include <curl/curlver.h> #include <curl/easy.h> -// Backwards compatibility for curl < 7.17.0 -#if LIBCURL_VERSION_NUM < 0x071100 -#define CURLOPT_DIRLISTONLY CURLOPT_FTPLISTONLY -#endif - static int write_data (void *buffer, size_t size, size_t nmemb, void *streamp) { @@ -149,6 +144,8 @@ octave_refcount<size_t> count; std::string host; + std::string url; + std::string userpwd; bool valid; bool ascii; mutable CURLcode errnum; @@ -187,8 +184,8 @@ rep->host = _host; init (user, passwd, std::cin, octave_stdout); - std::string url = "ftp://" + _host; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + _host; + setopt (CURLOPT_URL, rep->url.c_str ()); // Setup the link, with no transfer if (!error_state) @@ -205,6 +202,11 @@ setopt (CURLOPT_NOBODY, 0); + // Restore the default HTTP request method to GET after setting + // NOBODY to true and back to false. This is needed for backward + // compatibility with versions of libcurl < 7.18.2. + setopt (CURLOPT_HTTPGET, 1); + // Don't need to store the parameters here as we can't change // the URL after the handle is created std::string query_string = form_query_string (param); @@ -358,8 +360,8 @@ void put (const std::string& file, std::istream& is) const { - std::string url = "ftp://" + rep->host + "/" + file; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host + "/" + file; + setopt (CURLOPT_URL, rep->url.c_str ()); setopt (CURLOPT_UPLOAD, 1); setopt (CURLOPT_NOBODY, 0); set_istream (is); @@ -368,51 +370,51 @@ set_istream (std::cin); setopt (CURLOPT_NOBODY, 1); setopt (CURLOPT_UPLOAD, 0); - url = "ftp://" + rep->host; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host; + setopt (CURLOPT_URL, rep->url.c_str ()); } void get (const std::string& file, std::ostream& os) const { - std::string url = "ftp://" + rep->host + "/" + file; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host + "/" + file; + setopt (CURLOPT_URL, rep->url.c_str ()); setopt (CURLOPT_NOBODY, 0); set_ostream (os); if (! error_state) perform (); set_ostream (octave_stdout); setopt (CURLOPT_NOBODY, 1); - url = "ftp://" + rep->host; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host; + setopt (CURLOPT_URL, rep->url.c_str ()); } void dir (void) const { - std::string url = "ftp://" + rep->host + "/"; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host + "/"; + setopt (CURLOPT_URL, rep->url.c_str ()); setopt (CURLOPT_NOBODY, 0); if (! error_state) perform (); setopt (CURLOPT_NOBODY, 1); - url = "ftp://" + rep->host; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host; + setopt (CURLOPT_URL, rep->url.c_str ()); } string_vector list (void) const { std::ostringstream buf; - std::string url = "ftp://" + rep->host + "/"; + rep->url = "ftp://" + rep->host + "/"; setopt (CURLOPT_WRITEDATA, static_cast<void*> (&buf)); - setopt (CURLOPT_URL, url.c_str ()); + setopt (CURLOPT_URL, rep->url.c_str ()); setopt (CURLOPT_DIRLISTONLY, 1); setopt (CURLOPT_NOBODY, 0); if (! error_state) perform (); setopt (CURLOPT_NOBODY, 1); - url = "ftp://" + rep->host; + rep->url = "ftp://" + rep->host; setopt (CURLOPT_WRITEDATA, static_cast<void*> (&octave_stdout)); setopt (CURLOPT_DIRLISTONLY, 0); - setopt (CURLOPT_URL, url.c_str ()); + setopt (CURLOPT_URL, rep->url.c_str ()); // Count number of directory entries std::string str = buf.str (); @@ -445,8 +447,8 @@ { std::string path = pwd (); - std::string url = "ftp://" + rep->host + "/" + path + "/" + filename; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host + "/" + path + "/" + filename; + setopt (CURLOPT_URL, rep->url.c_str ()); setopt (CURLOPT_FILETIME, 1); setopt (CURLOPT_HEADERFUNCTION, throw_away); setopt (CURLOPT_WRITEFUNCTION, throw_away); @@ -479,8 +481,8 @@ setopt (CURLOPT_WRITEFUNCTION, write_data); setopt (CURLOPT_HEADERFUNCTION, 0); setopt (CURLOPT_FILETIME, 0); - url = "ftp://" + rep->host; - setopt (CURLOPT_URL, url.c_str ()); + rep->url = "ftp://" + rep->host; + setopt (CURLOPT_URL, rep->url.c_str ()); // The MDTM command seems to reset the path to the root with the // servers I tested with, so cd again into the correct path. Make @@ -562,11 +564,11 @@ setopt (CURLOPT_NOBODY, 1); // Set the username and password - std::string userpwd = user; + rep->userpwd = user; if (! passwd.empty ()) - userpwd += ":" + passwd; - if (! userpwd.empty ()) - setopt (CURLOPT_USERPWD, userpwd.c_str ()); + rep->userpwd += ":" + passwd; + if (! rep->userpwd.empty ()) + setopt (CURLOPT_USERPWD, rep->userpwd.c_str ()); // Define our callback to get called when there's data to be written. setopt (CURLOPT_WRITEFUNCTION, write_data);
new file mode 100644 --- /dev/null +++ b/libinterp/interp-core/action-container.h @@ -0,0 +1,342 @@ +/* + +Copyright (C) 1993-2012 John W. Eaton +Copyright (C) 2009-2010 VZLU Prague + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_action_container_h) +#define octave_action_container_h 1 + +// This class allows registering actions in a list for later +// execution, either explicitly or when the container goes out of +// scope. + +// FIXME -- is there a better name for this class? + +class +OCTINTERP_API +action_container +{ +public: + + // A generic unwind_protect element. Knows how to run itself and + // discard itself. Also, contains a pointer to the next element. + class elem + { + public: + elem (void) { } + + virtual void run (void) { } + + virtual ~elem (void) { } + + friend class action_container; + + private: + + // No copying! + + elem (const elem&); + + elem& operator = (const elem&); + }; + + // An element that merely runs a void (*)(void) function. + + class fcn_elem : public elem + { + public: + fcn_elem (void (*fptr) (void)) + : e_fptr (fptr) { } + + void run (void) { e_fptr (); } + + private: + void (*e_fptr) (void); + }; + + // An element that stores a variable of type T along with a void (*) (T) + // function pointer, and calls the function with the parameter. + + template <class T> + class fcn_arg_elem : public elem + { + public: + fcn_arg_elem (void (*fcn) (T), T arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + + // No copying! + + fcn_arg_elem (const fcn_arg_elem&); + + fcn_arg_elem& operator = (const fcn_arg_elem&); + + void (*e_fcn) (T); + T e_arg; + }; + + // An element that stores a variable of type T along with a + // void (*) (const T&) function pointer, and calls the function with + // the parameter. + + template <class T> + class fcn_crefarg_elem : public elem + { + public: + fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + void (*e_fcn) (const T&); + T e_arg; + }; + + // An element for calling a member function. + + template <class T> + class method_elem : public elem + { + public: + method_elem (T *obj, void (T::*method) (void)) + : e_obj (obj), e_method (method) { } + + void run (void) { (e_obj->*e_method) (); } + + private: + + T *e_obj; + void (T::*e_method) (void); + + // No copying! + + method_elem (const method_elem&); + + method_elem operator = (const method_elem&); + }; + + // An element for calling a member function with a single argument + + template <class T, class A> + class method_arg_elem : public elem + { + public: + method_arg_elem (T *obj, void (T::*method) (A), A arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (A); + A e_arg; + + // No copying! + + method_arg_elem (const method_arg_elem&); + + method_arg_elem operator = (const method_arg_elem&); + }; + + // An element for calling a member function with a single argument + + template <class T, class A> + class method_crefarg_elem : public elem + { + public: + method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (const A&); + A e_arg; + + // No copying! + + method_crefarg_elem (const method_crefarg_elem&); + + method_crefarg_elem operator = (const method_crefarg_elem&); + }; + + // An element that stores arbitrary variable, and restores it. + + template <class T> + class restore_var_elem : public elem + { + public: + restore_var_elem (T& ref, const T& val) + : e_ptr (&ref), e_val (val) { } + + void run (void) { *e_ptr = e_val; } + + private: + + // No copying! + + restore_var_elem (const restore_var_elem&); + + restore_var_elem& operator = (const restore_var_elem&); + + T *e_ptr, e_val; + }; + + // Deletes a class allocated using new. + + template <class T> + class delete_ptr_elem : public elem + { + public: + delete_ptr_elem (T *ptr) + : e_ptr (ptr) { } + + void run (void) { delete e_ptr; } + + private: + + T *e_ptr; + + // No copying! + + delete_ptr_elem (const delete_ptr_elem&); + + delete_ptr_elem operator = (const delete_ptr_elem&); + }; + + action_container (void) { } + + virtual ~action_container (void) { } + + virtual void add (elem *new_elem) = 0; + + // Call to void func (void). + void add_fcn (void (*fcn) (void)) + { + add (new fcn_elem (fcn)); + } + + // Call to void func (T). + template <class T> + void add_fcn (void (*action) (T), T val) + { + add (new fcn_arg_elem<T> (action, val)); + } + + // Call to void func (const T&). + template <class T> + void add_fcn (void (*action) (const T&), const T& val) + { + add (new fcn_crefarg_elem<T> (action, val)); + } + + // Call to T::method (void). + template <class T> + void add_method (T *obj, void (T::*method) (void)) + { + add (new method_elem<T> (obj, method)); + } + + // Call to T::method (A). + template <class T, class A> + void add_method (T *obj, void (T::*method) (A), A arg) + { + add (new method_arg_elem<T, A> (obj, method, arg)); + } + + // Call to T::method (const A&). + template <class T, class A> + void add_method (T *obj, void (T::*method) (const A&), const A& arg) + { + add (new method_crefarg_elem<T, A> (obj, method, arg)); + } + + // Call to delete (T*). + + template <class T> + void add_delete (T *obj) + { + add (new delete_ptr_elem<T> (obj)); + } + + // Protect any variable. + template <class T> + void protect_var (T& var) + { + add (new restore_var_elem<T> (var, var)); + } + + // Protect any variable, value given. + template <class T> + void protect_var (T& var, const T& val) + { + add (new restore_var_elem<T> (var, val)); + } + + operator bool (void) const { return ! empty (); } + + virtual void run_first (void) = 0; + + void run (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + run_first (); + } + + void run (void) { run (size ()); } + + virtual void discard_first (void) = 0; + + void discard (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + discard_first (); + } + + void discard (void) { discard (size ()); } + + virtual size_t size (void) const = 0; + + bool empty (void) const { return size () == 0; } + +private: + + // No copying! + + action_container (const action_container&); + + action_container& operator = (const action_container&); +}; + +#endif
--- a/libinterp/interp-core/defun-dld.h +++ b/libinterp/interp-core/defun-dld.h @@ -44,7 +44,7 @@ #define DEFUN_DLD(name, args_name, nargout_name, doc) \ DEFUN_DLD_INTERNAL (name, args_name, nargout_name, doc) -// This one can be used when `name' cannot be used directly (if it is +// This one can be used when 'name' cannot be used directly (if it is // already defined as a macro). In that case, name is already a // quoted string, and the internal name of the function must be passed // too (the convention is to use a prefix of "F", so "foo" becomes
--- a/libinterp/interp-core/dynamic-ld.cc +++ b/libinterp/interp-core/dynamic-ld.cc @@ -398,7 +398,7 @@ retval = f (oct_file, relative); if (! retval) - ::error ("failed to install .oct file function `%s'", + ::error ("failed to install .oct file function '%s'", fcn_name.c_str ()); } } @@ -468,7 +468,7 @@ retval = new octave_mex_function (function, have_fmex, mex_file, fcn_name); else - ::error ("failed to install .mex file function `%s'", + ::error ("failed to install .mex file function '%s'", fcn_name.c_str ()); } else
new file mode 100644 --- /dev/null +++ b/libinterp/interp-core/event-queue.h @@ -0,0 +1,126 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_event_queue_h) +#define octave_event_queue_h 1 + +#include <queue> +#include <memory> + +#include "action-container.h" + +class +OCTINTERP_API +event_queue : public action_container +{ +public: + + event_queue (void) : fifo () { } + + // Destructor should not raise an exception, so all actions + // registered should be exception-safe (but setting error_state is + // allowed). If you're not sure, see event_queue_safe. + + ~event_queue (void) { run (); } + + void add (elem *new_elem) + { + fifo.push (new_elem); + } + + void run_first (void) + { + if (! empty ()) + { + // No leak on exception! + std::auto_ptr<elem> ptr (fifo.front ()); + fifo.pop (); + ptr->run (); + } + } + + void discard_first (void) + { + if (! empty ()) + { + elem *ptr = fifo.front (); + fifo.pop (); + delete ptr; + } + } + + size_t size (void) const { return fifo.size (); } + +protected: + + std::queue<elem *> fifo; + +private: + + // No copying! + + event_queue (const event_queue&); + + event_queue& operator = (const event_queue&); +}; + +// Like event_queue, but this one will guard against the +// possibility of seeing an exception (or interrupt) in the cleanup +// actions. Not that we can do much about it, but at least we won't +// crash. + +class +event_queue_safe : public event_queue +{ +private: + + static void gripe_exception (void); + +public: + + event_queue_safe (void) : event_queue () { } + + ~event_queue_safe (void) + { + while (! empty ()) + { + try + { + run_first (); + } + catch (...) // Yes, the black hole. Remember we're in a dtor. + { + gripe_exception (); + } + } + } + +private: + + // No copying! + + event_queue_safe (const event_queue_safe&); + + event_queue_safe& operator = (const event_queue_safe&); +}; + +#endif
--- a/libinterp/interp-core/gl-render.cc +++ b/libinterp/interp-core/gl-render.cc @@ -582,7 +582,7 @@ } else { - warning ("opengl_renderer: cannot render object of type `%s'", + warning ("opengl_renderer: cannot render object of type '%s'", props.graphics_object_name ().c_str ()); } } @@ -2982,7 +2982,7 @@ } break; default: - warning ("opengl_renderer: unsupported marker `%s'", + warning ("opengl_renderer: unsupported marker '%s'", marker.c_str ()); break; }
--- a/libinterp/interp-core/gripes.cc +++ b/libinterp/interp-core/gripes.cc @@ -103,7 +103,7 @@ void gripe_invalid_value_specified (const char *name) { - warning ("invalid value specified for `%s'", name); + warning ("invalid value specified for '%s'", name); } void @@ -134,9 +134,9 @@ gripe_wrong_type_arg (const char *name, const char *s, bool is_error) { if (is_error) - error ("%s: wrong type argument `%s'", name, s); + error ("%s: wrong type argument '%s'", name, s); else - warning ("%s: wrong type argument `%s'", name, s); + warning ("%s: wrong type argument '%s'", name, s); } void @@ -165,14 +165,14 @@ gripe_wrong_type_arg_for_unary_op (const octave_value& op) { std::string type = op.type_name (); - error ("invalid operand `%s' for unary operator", type.c_str ()); + error ("invalid operand '%s' for unary operator", type.c_str ()); } void gripe_wrong_type_arg_for_binary_op (const octave_value& op) { std::string type = op.type_name (); - error ("invalid operand `%s' for binary operator", type.c_str ()); + error ("invalid operand '%s' for binary operator", type.c_str ()); } void
--- a/libinterp/interp-core/jit-ir.cc +++ b/libinterp/interp-core/jit-ir.cc @@ -97,6 +97,8 @@ (*iter)->print_dom (os); } os << std::endl; + + return os; } void
--- a/libinterp/interp-core/jit-ir.h +++ b/libinterp/interp-core/jit-ir.h @@ -42,6 +42,7 @@ JIT_METH(call); \ JIT_METH(extract_argument); \ JIT_METH(store_argument); \ + JIT_METH(return); \ JIT_METH(phi); \ JIT_METH(variable); \ JIT_METH(error_check); \ @@ -280,6 +281,10 @@ jit_use : public jit_internal_node<jit_value, jit_use> { public: + // some compilers don't allow us to use jit_internal_node without template + // paremeters + typedef jit_internal_node<jit_value, jit_use> PARENT_T; + jit_use (void) : muser (0), mindex (0) {} // we should really have a move operator, but not until c++11 :( @@ -305,7 +310,7 @@ void stash_value (jit_value *avalue, jit_instruction *auser = 0, size_t aindex = -1) { - jit_internal_node::stash_value (avalue); + PARENT_T::stash_value (avalue); mindex = aindex; muser = auser; } @@ -764,6 +769,10 @@ return true; } + jit_instruction *front (void) { return instructions.front (); } + + jit_instruction *back (void) { return instructions.back (); } + JIT_VALUE_ACCEPT; private: void internal_append (jit_instruction *instr); @@ -796,7 +805,7 @@ jit_phi_incomming (jit_phi *auser) : muser (auser) {} - jit_phi_incomming (const jit_phi_incomming& use) : jit_internal_node () + jit_phi_incomming (const jit_phi_incomming& use) { *this = use; } @@ -1145,6 +1154,21 @@ jit_call : public jit_instruction { public: + jit_call (const jit_operation& (*aoperation) (void)) + : moperation (aoperation ()) + { + const jit_function& ol = overload (); + if (ol.valid ()) + stash_type (ol.result ()); + } + + jit_call (const jit_operation& aoperation) : moperation (aoperation) + { + const jit_function& ol = overload (); + if (ol.valid ()) + stash_type (ol.result ()); + } + #define JIT_CALL_CONST(N) \ jit_call (const jit_operation& aoperation, \ OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \ @@ -1362,6 +1386,38 @@ }; class +jit_return : public jit_instruction +{ +public: + jit_return (void) {} + + jit_return (jit_value *retval) : jit_instruction (retval) {} + + jit_value *result (void) const + { + return argument_count () ? argument (0) : 0; + } + + jit_type *result_type (void) const + { + jit_value *res = result (); + return res ? res->type () : 0; + } + + virtual std::ostream& print (std::ostream& os, size_t indent = 0) const + { + print_indent (os, indent) << "return"; + + if (result ()) + os << " " << *result (); + + return os; + } + + JIT_VALUE_ACCEPT; +}; + +class jit_ir_walker { public:
--- a/libinterp/interp-core/jit-typeinfo.cc +++ b/libinterp/interp-core/jit-typeinfo.cc @@ -113,10 +113,10 @@ return obv; } -extern "C" void -octave_jit_grab_matrix (jit_matrix *result, jit_matrix *m) +extern "C" jit_matrix +octave_jit_grab_matrix (jit_matrix *m) { - *result = *m->array; + return *m->array; } extern "C" octave_base_value * @@ -130,12 +130,12 @@ return rep; } -extern "C" void -octave_jit_cast_matrix_any (jit_matrix *ret, octave_base_value *obv) +extern "C" jit_matrix +octave_jit_cast_matrix_any (octave_base_value *obv) { NDArray m = obv->array_value (); - *ret = m; obv->release (); + return m; } extern "C" octave_base_value * @@ -148,13 +148,13 @@ return rep; } -extern "C" void -octave_jit_cast_range_any (jit_range *ret, octave_base_value *obv) +extern "C" jit_range +octave_jit_cast_range_any (octave_base_value *obv) { jit_range r (obv->range_value ()); - *ret = r; obv->release (); + return r; } extern "C" double @@ -228,9 +228,9 @@ } } -extern "C" void -octave_jit_paren_subsasgn_impl (jit_matrix *ret, jit_matrix *mat, - octave_idx_type index, double value) +extern "C" jit_matrix +octave_jit_paren_subsasgn_impl (jit_matrix *mat, octave_idx_type index, + double value) { NDArray *array = mat->array; if (array->nelem () < index) @@ -240,7 +240,7 @@ data[index - 1] = value; mat->update (); - *ret = *mat; + return *mat; } static void @@ -272,12 +272,12 @@ } } -extern "C" void -octave_jit_paren_scalar_subsasgn (jit_matrix *ret, jit_matrix *mat, - double *indices, octave_idx_type idx_count, - double value) +extern "C" jit_matrix +octave_jit_paren_scalar_subsasgn (jit_matrix *mat, double *indices, + octave_idx_type idx_count, double value) { // FIXME: Replace this with a more optimal version + jit_matrix ret; try { Array<idx_vector> idx; @@ -286,17 +286,19 @@ Matrix temp (1, 1); temp.xelem(0) = value; mat->array->assign (idx, temp); - ret->update (mat->array); + ret.update (mat->array); } catch (const octave_execution_exception&) { gripe_library_execution_error (); } + + return ret; } -extern "C" void -octave_jit_paren_subsasgn_matrix_range (jit_matrix *result, jit_matrix *mat, - jit_range *index, double value) +extern "C" jit_matrix +octave_jit_paren_subsasgn_matrix_range (jit_matrix *mat, jit_range *index, + double value) { NDArray *array = mat->array; bool done = false; @@ -340,7 +342,9 @@ array->assign (idx, avalue); } - result->update (array); + jit_matrix ret; + ret.update (array); + return ret; } extern "C" double @@ -366,6 +370,16 @@ return idx < ndim ? mat->dimensions[idx] : 1; } +extern "C" octave_base_value * +octave_jit_create_undef (void) +{ + octave_value undef; + octave_base_value *ret = undef.internal_rep (); + ret->grab (); + + return ret; +} + extern "C" Complex octave_jit_complex_div (Complex lhs, Complex rhs) { @@ -552,6 +566,10 @@ llvm::FunctionType *ft = llvm::FunctionType::get (rtype, llvm_args, false); llvm_function = llvm::Function::Create (ft, llvm::Function::ExternalLinkage, aname, module); + + if (sret ()) + llvm_function->addAttribute (1, llvm::Attribute::StructRet); + if (call_conv == jit_convention::internal) llvm_function->addFnAttr (llvm::Attribute::AlwaysInline); } @@ -568,6 +586,16 @@ args (fn.args), call_conv (fn.call_conv), mcan_error (fn.mcan_error) {} +void +jit_function::erase (void) +{ + if (! llvm_function) + return; + + llvm_function->eraseFromParent (); + llvm_function = 0; +} + std::string jit_function::name (void) const { @@ -610,12 +638,18 @@ llvm::SmallVector<llvm::Value *, 10> llvm_args; llvm_args.reserve (in_args.size () + sret ()); - llvm::Value *sret_mem = 0; - llvm::Value *saved_stack = 0; + llvm::BasicBlock *insert_block = builder.GetInsertBlock (); + llvm::Function *parent = insert_block->getParent (); + assert (parent); + + // we insert allocas inside the prelude block to prevent stack overflows + llvm::BasicBlock& prelude = parent->getEntryBlock (); + llvm::IRBuilder<> pre_builder (&prelude, prelude.begin ()); + + llvm::AllocaInst *sret_mem = 0; if (sret ()) { - saved_stack = builder.CreateCall (stacksave); - sret_mem = builder.CreateAlloca (mresult->packed_type (call_conv)); + sret_mem = pre_builder.CreateAlloca (mresult->packed_type (call_conv)); llvm_args.push_back (sret_mem); } @@ -628,19 +662,23 @@ if (args[i]->pointer_arg (call_conv)) { - if (! saved_stack) - saved_stack = builder.CreateCall (stacksave); - - arg = builder.CreateAlloca (args[i]->to_llvm ()); - builder.CreateStore (in_args[i], arg); + llvm::Type *ty = args[i]->packed_type (call_conv); + llvm::Value *alloca = pre_builder.CreateAlloca (ty); + builder.CreateStore (arg, alloca); + arg = alloca; } llvm_args.push_back (arg); } - llvm::Value *ret = builder.CreateCall (llvm_function, llvm_args); - if (sret_mem) - ret = builder.CreateLoad (sret_mem); + llvm::CallInst *callinst = builder.CreateCall (llvm_function, llvm_args); + llvm::Value *ret = callinst; + + if (sret ()) + { + callinst->addAttribute (1, llvm::Attribute::StructRet); + ret = builder.CreateLoad (sret_mem); + } if (mresult) { @@ -649,14 +687,6 @@ ret = unpack (builder, ret); } - if (saved_stack) - { - llvm::Function *stackrestore - = llvm::Intrinsic::getDeclaration (module, - llvm::Intrinsic::stackrestore); - builder.CreateCall (stackrestore, saved_stack); - } - return ret; } @@ -681,7 +711,8 @@ } void -jit_function::do_return (llvm::IRBuilderD& builder, llvm::Value *rval) +jit_function::do_return (llvm::IRBuilderD& builder, llvm::Value *rval, + bool verify) { assert (! rval == ! mresult); @@ -692,14 +723,18 @@ rval = convert (builder, rval); if (sret ()) - builder.CreateStore (rval, llvm_function->arg_begin ()); + { + builder.CreateStore (rval, llvm_function->arg_begin ()); + builder.CreateRetVoid (); + } else builder.CreateRet (rval); } else builder.CreateRetVoid (); - llvm::verifyFunction (*llvm_function); + if (verify) + llvm::verifyFunction (*llvm_function); } void @@ -791,14 +826,15 @@ jit_operation::to_idx (const std::vector<jit_type*>& types) const { octave_idx_type numel = types.size (); - if (numel == 1) - numel = 2; + numel = std::max (2, numel); Array<octave_idx_type> idx (dim_vector (1, numel)); for (octave_idx_type i = 0; i < static_cast<octave_idx_type> (types.size ()); ++i) idx(i) = types[i]->type_id (); + if (types.size () == 0) + idx(0) = idx(1) = 0; if (types.size () == 1) { idx(1) = idx(0); @@ -1021,9 +1057,14 @@ // complex_ret is what is passed to C functions in order to get calling // convention right + llvm::Type *cmplx_inner_cont[] = {scalar_t, scalar_t}; + llvm::StructType *cmplx_inner = llvm::StructType::create (cmplx_inner_cont); + complex_ret = llvm::StructType::create (context, "complex_ret"); - llvm::Type *complex_ret_contents[] = {scalar_t, scalar_t}; - complex_ret->setBody (complex_ret_contents); + { + llvm::Type *contents[] = {cmplx_inner}; + complex_ret->setBody (contents); + } // create types any = new_type ("any", 0, any_t); @@ -1048,18 +1089,18 @@ // specify calling conventions // FIXME: We should detect architecture and do something sane based on that // here we assume x86 or x86_64 - matrix->mark_sret (); - matrix->mark_pointer_arg (); + matrix->mark_sret (jit_convention::external); + matrix->mark_pointer_arg (jit_convention::external); - range->mark_sret (); - range->mark_pointer_arg (); + range->mark_sret (jit_convention::external); + range->mark_pointer_arg (jit_convention::external); complex->set_pack (jit_convention::external, &jit_typeinfo::pack_complex); complex->set_unpack (jit_convention::external, &jit_typeinfo::unpack_complex); complex->set_packed_type (jit_convention::external, complex_ret); if (sizeof (void *) == 4) - complex->mark_sret (); + complex->mark_sret (jit_convention::external); paren_subsref_fn.initialize (module, engine); paren_subsasgn_fn.initialize (module, engine); @@ -1123,19 +1164,19 @@ binary_ops[op].add_overload (fn); } - // grab any - fn = create_function (jit_convention::external, "octave_jit_grab_any", any, - any); - fn.add_mapping (engine, &octave_jit_grab_any); - grab_fn.add_overload (fn); - grab_fn.stash_name ("grab"); - // grab matrix fn = create_function (jit_convention::external, "octave_jit_grab_matrix", matrix, matrix); fn.add_mapping (engine, &octave_jit_grab_matrix); grab_fn.add_overload (fn); + grab_fn.add_overload (create_identity (scalar)); + grab_fn.add_overload (create_identity (scalar_ptr)); + grab_fn.add_overload (create_identity (any_ptr)); + grab_fn.add_overload (create_identity (boolean)); + grab_fn.add_overload (create_identity (complex)); + grab_fn.add_overload (create_identity (index)); + // release any fn = create_function (jit_convention::external, "octave_jit_release_any", 0, any); @@ -1149,9 +1190,13 @@ fn.add_mapping (engine, &octave_jit_release_matrix); release_fn.add_overload (fn); - // copy - copy_fn.stash_name ("copy"); - copy_fn.add_overload (create_identity (scalar)); + // destroy + destroy_fn = release_fn; + destroy_fn.stash_name ("destroy"); + destroy_fn.add_overload (create_identity(scalar)); + destroy_fn.add_overload (create_identity(boolean)); + destroy_fn.add_overload (create_identity(index)); + destroy_fn.add_overload (create_identity(complex)); // now for binary scalar operations add_binary_op (scalar, octave_value::op_add, llvm::Instruction::FAdd); @@ -1318,9 +1363,9 @@ binary_ops[octave_value::op_div].add_overload (fn); binary_ops[octave_value::op_ldiv].add_overload (fn); - fn = mirror_binary (complex_div); - binary_ops[octave_value::op_ldiv].add_overload (fn); - binary_ops[octave_value::op_el_ldiv].add_overload (fn); + // fn = mirror_binary (complex_div); + // binary_ops[octave_value::op_ldiv].add_overload (fn); + // binary_ops[octave_value::op_el_ldiv].add_overload (fn); fn = create_function (jit_convention::external, "octave_jit_pow_complex_complex", complex, complex, @@ -1706,6 +1751,12 @@ scalar, matrix, index, index); end_fn.add_overload (fn); + // -------------------- create_undef -------------------- + create_undef_fn.stash_name ("create_undef"); + fn = create_function (jit_convention::external, "octave_jit_create_undef", + any); + create_undef_fn.add_overload (fn); + casts[any->type_id ()].stash_name ("(any)"); casts[scalar->type_id ()].stash_name ("(scalar)"); casts[complex->type_id ()].stash_name ("(complex)"); @@ -1836,6 +1887,9 @@ casts.resize (next_id + 1); jit_function any_id = create_identity (any); + jit_function grab_any = create_function (jit_convention::external, + "octave_jit_grab_any", any, any); + grab_any.add_mapping (engine, &octave_jit_grab_any); jit_function release_any = get_release (any); std::vector<jit_type *> args; args.resize (1); @@ -1846,6 +1900,7 @@ jit_type *btype = iter->second; args[0] = btype; + grab_fn.add_overload (jit_function (grab_any, btype, args)); release_fn.add_overload (jit_function (release_any, 0, args)); casts[any->type_id ()].add_overload (jit_function (any_id, any, args)); @@ -1965,8 +2020,11 @@ if (! identities[id].valid ()) { - jit_function fn = create_function (jit_convention::internal, "id", type, - type); + std::stringstream name; + name << "id_" << type->name (); + jit_function fn = create_function (jit_convention::internal, name.str (), + type, type); + llvm::BasicBlock *body = fn.new_block (); builder.SetInsertPoint (body); fn.do_return (builder, fn.argument (builder, 0)); @@ -2116,17 +2174,24 @@ llvm::Value *real = bld.CreateExtractElement (cplx, bld.getInt32 (0)); llvm::Value *imag = bld.CreateExtractElement (cplx, bld.getInt32 (1)); llvm::Value *ret = llvm::UndefValue::get (complex_ret); - ret = bld.CreateInsertValue (ret, real, 0); - return bld.CreateInsertValue (ret, imag, 1); + + unsigned int re_idx[] = {0, 0}; + unsigned int im_idx[] = {0, 1}; + ret = bld.CreateInsertValue (ret, real, re_idx); + return bld.CreateInsertValue (ret, imag, im_idx); } llvm::Value * jit_typeinfo::unpack_complex (llvm::IRBuilderD& bld, llvm::Value *result) { + unsigned int re_idx[] = {0, 0}; + unsigned int im_idx[] = {0, 1}; + llvm::Type *complex_t = get_complex ()->to_llvm (); - llvm::Value *real = bld.CreateExtractValue (result, 0); - llvm::Value *imag = bld.CreateExtractValue (result, 1); + llvm::Value *real = bld.CreateExtractValue (result, re_idx); + llvm::Value *imag = bld.CreateExtractValue (result, im_idx); llvm::Value *ret = llvm::UndefValue::get (complex_t); + ret = bld.CreateInsertElement (ret, real, bld.getInt32 (0)); return bld.CreateInsertElement (ret, imag, bld.getInt32 (1)); } @@ -2198,7 +2263,7 @@ if (ov.is_range ()) return get_range (); - if (ov.is_double_type ()) + if (ov.is_double_type () && ! ov.is_complex_type ()) { if (ov.is_real_scalar ()) return get_scalar ();
--- a/libinterp/interp-core/jit-typeinfo.h +++ b/libinterp/interp-core/jit-typeinfo.h @@ -66,6 +66,8 @@ struct jit_array { + jit_array () : array (0) {} + jit_array (T& from) : array (new T (from)) { update (); @@ -161,7 +163,7 @@ // retval. (on the stack) bool sret (jit_convention::type cc) const { return msret[cc]; } - void mark_sret (jit_convention::type cc = jit_convention::external) + void mark_sret (jit_convention::type cc) { msret[cc] = true; } // A function like: void foo (mytype arg0) @@ -169,7 +171,7 @@ // Basically just pass by reference. bool pointer_arg (jit_convention::type cc) const { return mpointer_arg[cc]; } - void mark_pointer_arg (jit_convention::type cc = jit_convention::external) + void mark_pointer_arg (jit_convention::type cc) { mpointer_arg[cc] = true; } // Convert into an equivalent form before calling. For example, complex is @@ -234,6 +236,9 @@ jit_function (const jit_function& fn); + // erase the interal LLVM function (if it exists). Will become invalid. + void erase (void); + template <typename T> void add_mapping (llvm::ExecutionEngine *engine, T fn) { @@ -278,7 +283,8 @@ llvm::Value *argument (llvm::IRBuilderD& builder, size_t idx) const; - void do_return (llvm::IRBuilderD& builder, llvm::Value *rval = 0); + void do_return (llvm::IRBuilderD& builder, llvm::Value *rval = 0, + bool verify = true); llvm::Function *to_llvm (void) const { return llvm_function; } @@ -452,6 +458,8 @@ static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; } + static jit_type *get_any_ptr (void) { return instance->any_ptr; } + static jit_type *get_range (void) { return instance->range; } static jit_type *get_string (void) { return instance->string; } @@ -498,9 +506,9 @@ return instance->release_fn.overload (type); } - static const jit_operation& copy (void) + static const jit_operation& destroy (void) { - return instance->copy_fn; + return instance->destroy_fn; } static const jit_operation& print_value (void) @@ -568,6 +576,11 @@ { return instance->do_end (value, index, count); } + + static const jit_operation& create_undef (void) + { + return instance->create_undef_fn; + } private: jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e); @@ -756,7 +769,7 @@ std::vector<jit_operation> unary_ops; jit_operation grab_fn; jit_operation release_fn; - jit_operation copy_fn; + jit_operation destroy_fn; jit_operation print_fn; jit_operation for_init_fn; jit_operation for_check_fn; @@ -767,6 +780,7 @@ jit_paren_subsasgn paren_subsasgn_fn; jit_operation end1_fn; jit_operation end_fn; + jit_operation create_undef_fn; jit_function any_call;
--- a/libinterp/interp-core/ls-hdf5.cc +++ b/libinterp/interp-core/ls-hdf5.cc @@ -438,7 +438,7 @@ hid_t int_sign = H5Tget_sign (type_id); if (int_sign == H5T_SGN_ERROR) - warning ("load: can't read `%s' (unknown datatype)", name); + warning ("load: can't read '%s' (unknown datatype)", name); else { if (int_sign == H5T_SGN_NONE) @@ -447,7 +447,7 @@ int slen = H5Tget_size (type_id); if (slen < 0) - warning ("load: can't read `%s' (unknown datatype)", name); + warning ("load: can't read '%s' (unknown datatype)", name); else { switch (slen) @@ -469,7 +469,7 @@ break; default: - warning ("load: can't read `%s' (unknown datatype)", + warning ("load: can't read '%s' (unknown datatype)", name); int_typ = ""; break; @@ -478,7 +478,7 @@ } #endif if (int_typ == "") - warning ("load: can't read `%s' (unknown datatype)", name); + warning ("load: can't read '%s' (unknown datatype)", name); else { // Matrix or scalar? @@ -523,7 +523,7 @@ } else { - warning ("load: can't read `%s' (unknown datatype)", name); + warning ("load: can't read '%s' (unknown datatype)", name); retval = 0; // unknown datatype; skip } @@ -540,7 +540,7 @@ { // should we attempt to handle invalid identifiers by converting // bad characters to '_', say? - warning ("load: skipping invalid identifier `%s' in hdf5 file", + warning ("load: skipping invalid identifier '%s' in hdf5 file", name); } @@ -899,7 +899,7 @@ H5Gclose (data_id); if (! retval) - error ("save: error while writing `%s' to hdf5 file", name.c_str ()); + error ("save: error while writing '%s' to hdf5 file", name.c_str ()); return retval; }
--- a/libinterp/interp-core/ls-mat-ascii.cc +++ b/libinterp/interp-core/ls-mat-ascii.cc @@ -178,7 +178,7 @@ } if (nr == 0 || nc == 0) - error ("load: file `%s' seems to be empty!", filename.c_str ()); + error ("load: file '%s' seems to be empty!", filename.c_str ()); is.clear (); is.seekg (pos); @@ -284,7 +284,7 @@ } else { - error ("load: failed to read matrix from file `%s'", + error ("load: failed to read matrix from file '%s'", filename.c_str ()); return retval; @@ -313,15 +313,15 @@ expected, total_count); } else - error ("load: failed to read matrix from file `%s'", + error ("load: failed to read matrix from file '%s'", filename.c_str ()); } else - error ("load: unable to extract matrix size from file `%s'", + error ("load: unable to extract matrix size from file '%s'", filename.c_str ()); } else - error ("load: unable to convert filename `%s' to valid identifier", + error ("load: unable to convert filename '%s' to valid identifier", filename.c_str ()); return retval;
--- a/libinterp/interp-core/ls-mat4.cc +++ b/libinterp/interp-core/ls-mat4.cc @@ -395,7 +395,7 @@ if (! is || error_state) { - error ("load: reading matrix data for `%s'", name); + error ("load: reading matrix data for '%s'", name); goto data_read_error; } @@ -408,7 +408,7 @@ if (! is || error_state) { - error ("load: reading imaginary matrix data for `%s'", name); + error ("load: reading imaginary matrix data for '%s'", name); goto data_read_error; } @@ -431,7 +431,7 @@ } data_read_error: - error ("load: trouble reading binary file `%s'", filename.c_str ()); + error ("load: trouble reading binary file '%s'", filename.c_str ()); return retval; }
--- a/libinterp/interp-core/ls-mat5.cc +++ b/libinterp/interp-core/ls-mat5.cc @@ -374,7 +374,7 @@ \ if (read_mat5_tag (is, swap, type, len)) \ { \ - error ("load: reading matrix data for `%s'", retval.c_str ()); \ + error ("load: reading matrix data for '%s'", retval.c_str ()); \ goto data_read_error; \ } \ \ @@ -385,7 +385,7 @@ \ if (! is || error_state) \ { \ - error ("load: reading matrix data for `%s'", retval.c_str ()); \ + error ("load: reading matrix data for '%s'", retval.c_str ()); \ goto data_read_error; \ } \ \ @@ -398,7 +398,7 @@ \ if (read_mat5_tag (is, swap, type, len)) \ { \ - error ("load: reading matrix data for `%s'", \ + error ("load: reading matrix data for '%s'", \ retval.c_str ()); \ goto data_read_error; \ } \ @@ -409,7 +409,7 @@ \ if (! is || error_state) \ { \ - error ("load: reading imaginary matrix data for `%s'", \ + error ("load: reading imaginary matrix data for '%s'", \ retval.c_str ()); \ goto data_read_error; \ } \ @@ -714,7 +714,7 @@ if (! is || error_state) { - error ("load: reading cell data for `%s'", nm.c_str ()); + error ("load: reading cell data for '%s'", nm.c_str ()); goto data_read_error; } @@ -756,7 +756,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading sparse row data for `%s'", retval.c_str ()); + error ("load: reading sparse row data for '%s'", retval.c_str ()); goto data_read_error; } @@ -767,7 +767,7 @@ if (! is || error_state) { - error ("load: reading sparse row data for `%s'", retval.c_str ()); + error ("load: reading sparse row data for '%s'", retval.c_str ()); goto data_read_error; } @@ -776,7 +776,7 @@ // col indices if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading sparse column data for `%s'", retval.c_str ()); + error ("load: reading sparse column data for '%s'", retval.c_str ()); goto data_read_error; } @@ -787,7 +787,7 @@ if (! is || error_state) { - error ("load: reading sparse column data for `%s'", retval.c_str ()); + error ("load: reading sparse column data for '%s'", retval.c_str ()); goto data_read_error; } @@ -796,7 +796,7 @@ // real data subelement if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + error ("load: reading sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -814,7 +814,7 @@ if (! is || error_state) { - error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + error ("load: reading sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -827,7 +827,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + error ("load: reading sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -836,7 +836,7 @@ if (! is || error_state) { - error ("load: reading imaginary sparse matrix data for `%s'", + error ("load: reading imaginary sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1144,7 +1144,7 @@ // Fall-through case MAT_FILE_STRUCT_CLASS: { - Octave_map m (dim_vector (1, 1)); + Octave_map m (dims); int32_t fn_type; int32_t fn_len; int32_t field_name_length; @@ -1319,7 +1319,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1330,7 +1330,7 @@ if (! is || error_state) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1344,7 +1344,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1354,7 +1354,7 @@ if (! is || error_state) { - error ("load: reading imaginary matrix data for `%s'", + error ("load: reading imaginary matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1385,7 +1385,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1396,7 +1396,7 @@ if (! is || error_state) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1423,7 +1423,7 @@ if (read_mat5_tag (is, swap, type, len)) { - error ("load: reading matrix data for `%s'", retval.c_str ()); + error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1433,7 +1433,7 @@ if (! is || error_state) { - error ("load: reading imaginary matrix data for `%s'", + error ("load: reading imaginary matrix data for '%s'", retval.c_str ()); goto data_read_error; } @@ -1505,11 +1505,11 @@ data_read_error: early_read_error: - error ("load: trouble reading binary file `%s'", filename.c_str ()); + error ("load: trouble reading binary file '%s'", filename.c_str ()); return std::string (); skip_ahead: - warning ("skipping over `%s'", retval.c_str ()); + warning ("skipping over '%s'", retval.c_str ()); is.seekg (pos + static_cast<std::streamoff> (element_length)); return read_mat5_binary_element (is, filename, swap, global, tc); } @@ -2429,6 +2429,10 @@ } os.write (reinterpret_cast<char *> (&flags), 4); + // Matlab seems to have trouble reading files that have nzmax == 0 at + // this point in the file. + if (nnz_32 == 0) + nnz_32 = 1; os.write (reinterpret_cast<char *> (&nnz_32), 4); write_mat5_tag (os, miINT32, dim_len); @@ -2713,7 +2717,7 @@ return true; error_cleanup: - error ("save: error while writing `%s' to MAT file", name.c_str ()); + error ("save: error while writing '%s' to MAT file", name.c_str ()); return false; }
--- a/libinterp/interp-core/ls-oct-binary.cc +++ b/libinterp/interp-core/ls-oct-binary.cc @@ -256,7 +256,7 @@ if (!tc.load_binary (is, swap, fmt)) { data_read_error: - error ("load: trouble reading binary file `%s'", filename.c_str ()); + error ("load: trouble reading binary file '%s'", filename.c_str ()); } return retval;
--- a/libinterp/interp-core/mex.cc +++ b/libinterp/interp-core/mex.cc @@ -104,175 +104,12 @@ // ------------------------------------------------------------------ -// A class to provide the default implemenation of some of the virtual -// functions declared in the mxArray class. - -class mxArray_base : public mxArray +void +mxArray_base::error (const char *msg) const { -protected: - - mxArray_base (void) : mxArray (xmxArray ()) { } - -public: - - mxArray *dup (void) const = 0; - - ~mxArray_base (void) { } - - bool is_octave_value (void) const { return false; } - - int is_cell (void) const = 0; - - int is_char (void) const = 0; - - int is_class (const char *name_arg) const - { - int retval = 0; - - const char *cname = get_class_name (); - - if (cname && name_arg) - retval = ! strcmp (cname, name_arg); - - return retval; - } - - int is_complex (void) const = 0; - - int is_double (void) const = 0; - - int is_function_handle (void) const = 0; - - int is_int16 (void) const = 0; - - int is_int32 (void) const = 0; - - int is_int64 (void) const = 0; - - int is_int8 (void) const = 0; - - int is_logical (void) const = 0; - - int is_numeric (void) const = 0; - - int is_single (void) const = 0; - - int is_sparse (void) const = 0; - - int is_struct (void) const = 0; - - int is_uint16 (void) const = 0; - - int is_uint32 (void) const = 0; - - int is_uint64 (void) const = 0; - - int is_uint8 (void) const = 0; - - int is_logical_scalar (void) const - { - return is_logical () && get_number_of_elements () == 1; - } - - int is_logical_scalar_true (void) const = 0; - - mwSize get_m (void) const = 0; - - mwSize get_n (void) const = 0; - - mwSize *get_dimensions (void) const = 0; - - mwSize get_number_of_dimensions (void) const = 0; - - void set_m (mwSize m) = 0; - - void set_n (mwSize n) = 0; - - void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0; - - mwSize get_number_of_elements (void) const = 0; - - int is_empty (void) const = 0; - - mxClassID get_class_id (void) const = 0; - - const char *get_class_name (void) const = 0; - - void set_class_name (const char *name_arg) = 0; - - mxArray *get_cell (mwIndex /*idx*/) const - { - invalid_type_error (); - return 0; - } - - void set_cell (mwIndex idx, mxArray *val) = 0; - - double get_scalar (void) const = 0; - - void *get_data (void) const = 0; - - void *get_imag_data (void) const = 0; - - void set_data (void *pr) = 0; - - void set_imag_data (void *pi) = 0; - - mwIndex *get_ir (void) const = 0; - - mwIndex *get_jc (void) const = 0; - - mwSize get_nzmax (void) const = 0; - - void set_ir (mwIndex *ir) = 0; - - void set_jc (mwIndex *jc) = 0; - - void set_nzmax (mwSize nzmax) = 0; - - int add_field (const char *key) = 0; - - void remove_field (int key_num) = 0; - - mxArray *get_field_by_number (mwIndex index, int key_num) const = 0; - - void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0; - - int get_number_of_fields (void) const = 0; - - const char *get_field_name_by_number (int key_num) const = 0; - - int get_field_number (const char *key) const = 0; - - int get_string (char *buf, mwSize buflen) const = 0; - - char *array_to_string (void) const = 0; - - mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0; - - size_t get_element_size (void) const = 0; - - bool mutation_needed (void) const { return false; } - - mxArray *mutate (void) const { return 0; } - -protected: - - octave_value as_octave_value (void) const = 0; - - mxArray_base (const mxArray_base&) : mxArray (xmxArray ()) { } - - void invalid_type_error (void) const - { - error ("invalid type for operation"); - } - - void error (const char *msg) const - { - // FIXME - ::error ("%s", msg); - } -}; + // FIXME + ::error ("%s", msg); +} static mwIndex calc_single_subscript_internal (mwSize ndims, const mwSize *dims, @@ -327,14 +164,11 @@ : mxArray_base (), val (ov), mutate_flag (false), id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { } - mxArray *dup (void) const + mxArray_base *dup (void) const { return new mxArray_octave_value (*this); } + + mxArray *as_mxArray (void) const { - mxArray *retval = val.as_mxArray (); - - if (! retval) - retval = new mxArray_octave_value (*this); - - return retval; + return val.as_mxArray (); } ~mxArray_octave_value (void) @@ -411,7 +245,7 @@ { ndims = val.ndims (); - dims = static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))); + dims = static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))); dim_vector dv = val.dims (); @@ -488,7 +322,7 @@ if (! class_name) { std::string s = val.class_name (); - class_name = strsave (s.c_str ()); + class_name = mxArray::strsave (s.c_str ()); } return class_name; @@ -629,7 +463,7 @@ { mwSize nel = get_number_of_elements (); - buf = static_cast<char *> (malloc (nel + 1)); + buf = static_cast<char *> (mxArray::malloc (nel + 1)); if (buf) { @@ -693,14 +527,15 @@ mxArray *mutate (void) const { return val.as_mxArray (); } + octave_value as_octave_value (void) const { return val; } + protected: - octave_value as_octave_value (void) const { return val; } - mxArray_octave_value (const mxArray_octave_value& arg) : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag), - id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims), - dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0) + id (arg.id), class_name (mxArray::strsave (arg.class_name)), + ndims (arg.ndims), + dims (ndims > 0 ? static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))) : 0) { if (dims) { @@ -743,7 +578,7 @@ mxArray_matlab (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg) : mxArray_base (), class_name (0), id (id_arg), ndims (ndims_arg < 2 ? 2 : ndims_arg), - dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) + dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize)))) { if (ndims_arg < 2) { @@ -766,7 +601,7 @@ mxArray_matlab (mxClassID id_arg, const dim_vector& dv) : mxArray_base (), class_name (0), id (id_arg), ndims (dv.length ()), - dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) + dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize)))) { for (mwIndex i = 0; i < ndims; i++) dims[i] = dv(i); @@ -782,7 +617,7 @@ mxArray_matlab (mxClassID id_arg, mwSize m, mwSize n) : mxArray_base (), class_name (0), id (id_arg), ndims (2), - dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) + dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize)))) { dims[0] = m; dims[1] = n; @@ -911,7 +746,7 @@ void set_class_name (const char *name_arg) { mxFree (class_name); - class_name = static_cast<char *> (malloc (strlen (name_arg) + 1)); + class_name = static_cast<char *> (mxArray::malloc (strlen (name_arg) + 1)); strcpy (class_name, name_arg); } @@ -1069,9 +904,9 @@ protected: mxArray_matlab (const mxArray_matlab& val) - : mxArray_base (val), class_name (strsave (val.class_name)), + : mxArray_base (val), class_name (mxArray::strsave (val.class_name)), id (val.id), ndims (val.ndims), - dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) + dims (static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize)))) { for (mwIndex i = 0; i < ndims; i++) dims[i] = val.dims[i]; @@ -1122,23 +957,23 @@ mxArray_number (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg, mxComplexity flag = mxREAL) : mxArray_matlab (id_arg, ndims_arg, dims_arg), - pr (calloc (get_number_of_elements (), get_element_size ())), - pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), + pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { } mxArray_number (mxClassID id_arg, const dim_vector& dv, mxComplexity flag = mxREAL) : mxArray_matlab (id_arg, dv), - pr (calloc (get_number_of_elements (), get_element_size ())), - pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), + pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { } mxArray_number (mxClassID id_arg, mwSize m, mwSize n, mxComplexity flag = mxREAL) : mxArray_matlab (id_arg, m, n), - pr (calloc (get_number_of_elements (), get_element_size ())), - pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), + pi (flag == mxCOMPLEX ? mxArray::calloc (get_number_of_elements (), get_element_size ()) : 0) { } mxArray_number (mxClassID id_arg, double val) : mxArray_matlab (id_arg, 1, 1), - pr (calloc (get_number_of_elements (), get_element_size ())), + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), pi (0) { double *dpr = static_cast<double *> (pr); @@ -1147,7 +982,7 @@ mxArray_number (mxClassID id_arg, mxLogical val) : mxArray_matlab (id_arg, 1, 1), - pr (calloc (get_number_of_elements (), get_element_size ())), + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), pi (0) { mxLogical *lpr = static_cast<mxLogical *> (pr); @@ -1158,7 +993,7 @@ : mxArray_matlab (mxCHAR_CLASS, str ? (strlen (str) ? 1 : 0) : 0, str ? strlen (str) : 0), - pr (calloc (get_number_of_elements (), get_element_size ())), + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), pi (0) { mxChar *cpr = static_cast<mxChar *> (pr); @@ -1170,7 +1005,7 @@ // FIXME?? mxArray_number (mwSize m, const char **str) : mxArray_matlab (mxCHAR_CLASS, m, max_str_len (m, str)), - pr (calloc (get_number_of_elements (), get_element_size ())), + pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), pi (0) { mxChar *cpr = static_cast<mxChar *> (pr); @@ -1193,7 +1028,7 @@ } } - mxArray_number *dup (void) const { return new mxArray_number (*this); } + mxArray_base *dup (void) const { return new mxArray_number (*this); } ~mxArray_number (void) { @@ -1305,7 +1140,7 @@ mwSize nel = get_number_of_elements (); - char *buf = static_cast<char *> (malloc (nel + 1)); + char *buf = static_cast<char *> (mxArray::malloc (nel + 1)); if (buf) { @@ -1320,35 +1155,6 @@ return buf; } -protected: - - template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> - octave_value - int_to_ov (const dim_vector& dv) const - { - octave_value retval; - - mwSize nel = get_number_of_elements (); - - ELT_T *ppr = static_cast<ELT_T *> (pr); - - if (pi) - error ("complex integer types are not supported"); - else - { - ARRAY_T val (dv); - - ARRAY_ELT_T *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } - - return retval; - } - octave_value as_octave_value (void) const { octave_value retval; @@ -1483,10 +1289,39 @@ return retval; } +protected: + + template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> + octave_value + int_to_ov (const dim_vector& dv) const + { + octave_value retval; + + mwSize nel = get_number_of_elements (); + + ELT_T *ppr = static_cast<ELT_T *> (pr); + + if (pi) + error ("complex integer types are not supported"); + else + { + ARRAY_T val (dv); + + ARRAY_ELT_T *ptr = val.fortran_vec (); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = ppr[i]; + + retval = val; + } + + return retval; + } + mxArray_number (const mxArray_number& val) : mxArray_matlab (val), - pr (malloc (get_number_of_elements () * get_element_size ())), - pi (val.pi ? malloc (get_number_of_elements () * get_element_size ()) : 0) + pr (mxArray::malloc (get_number_of_elements () * get_element_size ())), + pi (val.pi ? mxArray::malloc (get_number_of_elements () * get_element_size ()) : 0) { size_t nbytes = get_number_of_elements () * get_element_size (); @@ -1517,13 +1352,13 @@ mxArray_sparse (mxClassID id_arg, mwSize m, mwSize n, mwSize nzmax_arg, mxComplexity flag = mxREAL) : mxArray_matlab (id_arg, m, n), nzmax (nzmax_arg), - pr (calloc (nzmax, get_element_size ())), - pi (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0), - ir (static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex)))), - jc (static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex)))) + pr (mxArray::calloc (nzmax, get_element_size ())), + pi (flag == mxCOMPLEX ? mxArray::calloc (nzmax, get_element_size ()) : 0), + ir (static_cast<mwIndex *> (mxArray::calloc (nzmax, sizeof (mwIndex)))), + jc (static_cast<mwIndex *> (mxArray::calloc (n + 1, sizeof (mwIndex)))) { } - mxArray_sparse *dup (void) const { return new mxArray_sparse (*this); } + mxArray_base *dup (void) const { return new mxArray_sparse (*this); } ~mxArray_sparse (void) { @@ -1557,8 +1392,6 @@ void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; } -protected: - octave_value as_octave_value (void) const { octave_value retval; @@ -1651,10 +1484,10 @@ mxArray_sparse (const mxArray_sparse& val) : mxArray_matlab (val), nzmax (val.nzmax), - pr (malloc (nzmax * get_element_size ())), - pi (val.pi ? malloc (nzmax * get_element_size ()) : 0), - ir (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))), - jc (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))) + pr (mxArray::malloc (nzmax * get_element_size ())), + pi (val.pi ? mxArray::malloc (nzmax * get_element_size ()) : 0), + ir (static_cast<mwIndex *> (mxArray::malloc (nzmax * sizeof (mwIndex)))), + jc (static_cast<mwIndex *> (mxArray::malloc (nzmax * sizeof (mwIndex)))) { size_t nbytes = nzmax * get_element_size (); @@ -1686,24 +1519,24 @@ mxArray_struct (mwSize ndims_arg, const mwSize *dims_arg, int num_keys_arg, const char **keys) : mxArray_matlab (mxSTRUCT_CLASS, ndims_arg, dims_arg), nfields (num_keys_arg), - fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), - data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) + fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))), + data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) { init (keys); } mxArray_struct (const dim_vector& dv, int num_keys_arg, const char **keys) : mxArray_matlab (mxSTRUCT_CLASS, dv), nfields (num_keys_arg), - fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), - data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) + fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))), + data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) { init (keys); } mxArray_struct (mwSize m, mwSize n, int num_keys_arg, const char **keys) : mxArray_matlab (mxSTRUCT_CLASS, m, n), nfields (num_keys_arg), - fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), - data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) + fields (static_cast<char **> (mxArray::calloc (nfields, sizeof (char *)))), + data (static_cast<mxArray **> (mxArray::calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) { init (keys); } @@ -1711,10 +1544,10 @@ void init (const char **keys) { for (int i = 0; i < nfields; i++) - fields[i] = strsave (keys[i]); + fields[i] = mxArray::strsave (keys[i]); } - mxArray_struct *dup (void) const { return new mxArray_struct (*this); } + mxArray_base *dup (void) const { return new mxArray_struct (*this); } ~mxArray_struct (void) { @@ -1743,13 +1576,13 @@ if (fields) { - fields[nfields-1] = strsave (key); + fields[nfields-1] = mxArray::strsave (key); mwSize nel = get_number_of_elements (); mwSize ntot = nfields * nel; - mxArray **new_data = static_cast<mxArray **> (malloc (ntot * sizeof (mxArray *))); + mxArray **new_data = static_cast<mxArray **> (mxArray::malloc (ntot * sizeof (mxArray *))); if (new_data) { @@ -1790,9 +1623,9 @@ int new_nfields = nfields - 1; - char **new_fields = static_cast<char **> (malloc (new_nfields * sizeof (char *))); - - mxArray **new_data = static_cast<mxArray **> (malloc (new_nfields * nel * sizeof (mxArray *))); + char **new_fields = static_cast<char **> (mxArray::malloc (new_nfields * sizeof (char *))); + + mxArray **new_data = static_cast<mxArray **> (mxArray::malloc (new_nfields * nel * sizeof (mxArray *))); for (int i = 0; i < key_num; i++) new_fields[i] = fields[i]; @@ -1863,8 +1696,6 @@ void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } -protected: - octave_value as_octave_value (void) const { dim_vector dv = dims_to_dim_vector (); @@ -1901,11 +1732,11 @@ mxArray_struct (const mxArray_struct& val) : mxArray_matlab (val), nfields (val.nfields), - fields (static_cast<char **> (malloc (nfields * sizeof (char *)))), - data (static_cast<mxArray **> (malloc (nfields * get_number_of_elements () * sizeof (mxArray *)))) + fields (static_cast<char **> (mxArray::malloc (nfields * sizeof (char *)))), + data (static_cast<mxArray **> (mxArray::malloc (nfields * get_number_of_elements () * sizeof (mxArray *)))) { for (int i = 0; i < nfields; i++) - fields[i] = strsave (val.fields[i]); + fields[i] = mxArray::strsave (val.fields[i]); mwSize nel = get_number_of_elements (); @@ -1930,17 +1761,17 @@ mxArray_cell (mwSize ndims_arg, const mwSize *dims_arg) : mxArray_matlab (mxCELL_CLASS, ndims_arg, dims_arg), - data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } + data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { } mxArray_cell (const dim_vector& dv) : mxArray_matlab (mxCELL_CLASS, dv), - data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } + data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { } mxArray_cell (mwSize m, mwSize n) : mxArray_matlab (mxCELL_CLASS, m, n), - data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } - - mxArray_cell *dup (void) const { return new mxArray_cell (*this); } + data (static_cast<mxArray **> (mxArray::calloc (get_number_of_elements (), sizeof (mxArray *)))) { } + + mxArray_base *dup (void) const { return new mxArray_cell (*this); } ~mxArray_cell (void) { @@ -1963,8 +1794,6 @@ void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } -protected: - octave_value as_octave_value (void) const { dim_vector dv = dims_to_dim_vector (); @@ -1987,7 +1816,7 @@ mxArray_cell (const mxArray_cell& val) : mxArray_matlab (val), - data (static_cast<mxArray **> (malloc (get_number_of_elements () * sizeof (mxArray *)))) + data (static_cast<mxArray **> (mxArray::malloc (get_number_of_elements () * sizeof (mxArray *)))) { mwSize nel = get_number_of_elements (); @@ -2062,11 +1891,11 @@ mxArray::set_name (const char *name_arg) { mxFree (name); - name = strsave (name_arg); + name = mxArray::strsave (name_arg); } octave_value -mxArray::as_octave_value (mxArray *ptr) +mxArray::as_octave_value (const mxArray *ptr) { return ptr ? ptr->as_octave_value () : octave_value (Matrix ()); } @@ -2532,7 +2361,7 @@ void * mxCalloc (size_t n, size_t size) { - return mex_context ? mex_context->calloc (n, size) : calloc (n, size); + return mex_context ? mex_context->calloc (n, size) : ::calloc (n, size); } void * @@ -3180,8 +3009,8 @@ } int -mexCallMATLAB (int nargout, mxArray *argout[], int nargin, mxArray *argin[], - const char *fname) +mexCallMATLAB (int nargout, mxArray *argout[], int nargin, + mxArray *argin[], const char *fname) { octave_value_list args; @@ -3386,7 +3215,7 @@ } int -mexPutVariable (const char *space, const char *name, mxArray *ptr) +mexPutVariable (const char *space, const char *name, const mxArray *ptr) { if (! ptr) return 1;
--- a/libinterp/interp-core/mexproto.h +++ b/libinterp/interp-core/mexproto.h @@ -87,7 +87,8 @@ extern OCTINTERP_API mxArray *mexGetVariable (const char *space, const char *name); extern OCTINTERP_API const mxArray *mexGetVariablePtr (const char *space, const char *name); -extern OCTINTERP_API int mexPutVariable (const char *space, const char *name, mxArray *ptr); +extern OCTINTERP_API int mexPutVariable (const char *space, const char *name, + const mxArray *ptr); extern OCTINTERP_API void mexMakeArrayPersistent (mxArray *ptr); extern OCTINTERP_API void mexMakeMemoryPersistent (void *ptr);
--- a/libinterp/interp-core/module.mk +++ b/libinterp/interp-core/module.mk @@ -4,14 +4,15 @@ interp-core/mxarray.in.h \ interp-core/oct-errno.in.cc -JIT_INCLUDES = \ +JIT_INC = \ interp-core/jit-util.h \ interp-core/jit-typeinfo.h \ interp-core/jit-ir.h \ interp-core/pt-jit.h -INTERP_CORE_INCLUDES = \ +INTERP_CORE_INC = \ interp-core/Cell.h \ + interp-core/action-container.h \ interp-core/c-file-ptr-stream.h \ interp-core/comment-list.h \ interp-core/cutils.h \ @@ -19,6 +20,7 @@ interp-core/defun-int.h \ interp-core/display.h \ interp-core/dynamic-ld.h \ + interp-core/event-queue.h \ interp-core/gl-render.h \ interp-core/gl2ps-renderer.h \ interp-core/gl2ps.h \ @@ -57,7 +59,7 @@ interp-core/xnorm.h \ interp-core/xpow.h \ interp-core/zfstream.h \ - $(JIT_INCLUDES) + $(JIT_INC) JIT_SRC = \ interp-core/jit-util.cc \ @@ -109,8 +111,11 @@ $(JIT_SRC) \ $(C_INTERP_CORE_SRC) -## FIXME: I don't believe this rule actually fires -display.df display.lo: CPPFLAGS += $(X11_FLAGS) +## FIXME: Automake does not support per-object rules. +## These rules could be emulated by creating a new convenience +## library and using per-library rules. Or we can just live +## without the rule since there haven't been any problems. (09/18/2012) +#display.df display.lo: CPPFLAGS += $(X11_FLAGS) ## Special rules for sources which must be built before rest of compilation. interp-core/oct-errno.cc: interp-core/oct-errno.in.cc Makefile @@ -132,3 +137,4 @@ noinst_LTLIBRARIES += interp-core/libinterp-core.la interp_core_libinterp_core_la_SOURCES = $(INTERP_CORE_SRC) +interp_core_libinterp_core_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS)
--- a/libinterp/interp-core/mxarray.in.h +++ b/libinterp/interp-core/mxarray.in.h @@ -88,6 +88,7 @@ */ typedef %OCTAVE_IDX_TYPE% mwSize; typedef %OCTAVE_IDX_TYPE% mwIndex; +typedef %OCTAVE_IDX_TYPE% mwSignedIndex; #if ! defined (MXARRAY_TYPEDEFS_ONLY) @@ -115,13 +116,174 @@ rep->METHOD_CALL; \ } -// This just provides a way to avoid infinite recursion when building -// mxArray objects. +// A class to provide the default implemenation of some of the virtual +// functions declared in the mxArray class. + +class mxArray; + +class mxArray_base +{ +protected: + + mxArray_base (void) { } + +public: + + virtual mxArray_base *dup (void) const = 0; + + virtual mxArray *as_mxArray (void) const { return 0; } + + virtual ~mxArray_base (void) { } + + virtual bool is_octave_value (void) const { return false; } + + virtual int is_cell (void) const = 0; + + virtual int is_char (void) const = 0; + + virtual int is_class (const char *name_arg) const + { + int retval = 0; + + const char *cname = get_class_name (); + + if (cname && name_arg) + retval = ! strcmp (cname, name_arg); + + return retval; + } + + virtual int is_complex (void) const = 0; + + virtual int is_double (void) const = 0; + + virtual int is_function_handle (void) const = 0; + + virtual int is_int16 (void) const = 0; + + virtual int is_int32 (void) const = 0; + + virtual int is_int64 (void) const = 0; + + virtual int is_int8 (void) const = 0; + + virtual int is_logical (void) const = 0; + + virtual int is_numeric (void) const = 0; + + virtual int is_single (void) const = 0; + + virtual int is_sparse (void) const = 0; + + virtual int is_struct (void) const = 0; + + virtual int is_uint16 (void) const = 0; + + virtual int is_uint32 (void) const = 0; + + virtual int is_uint64 (void) const = 0; + + virtual int is_uint8 (void) const = 0; + + virtual int is_logical_scalar (void) const + { + return is_logical () && get_number_of_elements () == 1; + } + + virtual int is_logical_scalar_true (void) const = 0; + + virtual mwSize get_m (void) const = 0; + + virtual mwSize get_n (void) const = 0; + + virtual mwSize *get_dimensions (void) const = 0; + + virtual mwSize get_number_of_dimensions (void) const = 0; -struct -xmxArray -{ - xmxArray (void) { } + virtual void set_m (mwSize m) = 0; + + virtual void set_n (mwSize n) = 0; + + virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0; + + virtual mwSize get_number_of_elements (void) const = 0; + + virtual int is_empty (void) const = 0; + + virtual mxClassID get_class_id (void) const = 0; + + virtual const char *get_class_name (void) const = 0; + + virtual void set_class_name (const char *name_arg) = 0; + + virtual mxArray *get_cell (mwIndex /*idx*/) const + { + invalid_type_error (); + return 0; + } + + virtual void set_cell (mwIndex idx, mxArray *val) = 0; + + virtual double get_scalar (void) const = 0; + + virtual void *get_data (void) const = 0; + + virtual void *get_imag_data (void) const = 0; + + virtual void set_data (void *pr) = 0; + + virtual void set_imag_data (void *pi) = 0; + + virtual mwIndex *get_ir (void) const = 0; + + virtual mwIndex *get_jc (void) const = 0; + + virtual mwSize get_nzmax (void) const = 0; + + virtual void set_ir (mwIndex *ir) = 0; + + virtual void set_jc (mwIndex *jc) = 0; + + virtual void set_nzmax (mwSize nzmax) = 0; + + virtual int add_field (const char *key) = 0; + + virtual void remove_field (int key_num) = 0; + + virtual mxArray *get_field_by_number (mwIndex index, int key_num) const = 0; + + virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0; + + virtual int get_number_of_fields (void) const = 0; + + virtual const char *get_field_name_by_number (int key_num) const = 0; + + virtual int get_field_number (const char *key) const = 0; + + virtual int get_string (char *buf, mwSize buflen) const = 0; + + virtual char *array_to_string (void) const = 0; + + virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0; + + virtual size_t get_element_size (void) const = 0; + + virtual bool mutation_needed (void) const { return false; } + + virtual mxArray *mutate (void) const { return 0; } + + virtual octave_value as_octave_value (void) const = 0; + +protected: + + mxArray_base (const mxArray_base&) { } + + void invalid_type_error (void) const + { + error ("invalid type for operation"); + } + + void error (const char *msg) const; }; // The main interface class. The representation can be based on an @@ -164,138 +326,147 @@ mxArray (mwSize m, mwSize n); - virtual mxArray *dup (void) const + mxArray *dup (void) const { - mxArray *new_rep = rep->dup (); + mxArray *retval = rep->as_mxArray (); - return new mxArray (new_rep, name); + if (retval) + retval->set_name (name); + else + { + mxArray_base *new_rep = rep->dup (); + + retval = new mxArray (new_rep, name); + } + + return retval; } - virtual ~mxArray (void); + ~mxArray (void); - virtual bool is_octave_value (void) const { return rep->is_octave_value (); } + bool is_octave_value (void) const { return rep->is_octave_value (); } - virtual int is_cell (void) const { return rep->is_cell (); } + int is_cell (void) const { return rep->is_cell (); } - virtual int is_char (void) const { return rep->is_char (); } + int is_char (void) const { return rep->is_char (); } - virtual int is_class (const char *name_arg) const { return rep->is_class (name_arg); } + int is_class (const char *name_arg) const { return rep->is_class (name_arg); } - virtual int is_complex (void) const { return rep->is_complex (); } + int is_complex (void) const { return rep->is_complex (); } - virtual int is_double (void) const { return rep->is_double (); } + int is_double (void) const { return rep->is_double (); } - virtual int is_function_handle (void) const { return rep->is_function_handle (); } + int is_function_handle (void) const { return rep->is_function_handle (); } - virtual int is_int16 (void) const { return rep->is_int16 (); } + int is_int16 (void) const { return rep->is_int16 (); } - virtual int is_int32 (void) const { return rep->is_int32 (); } + int is_int32 (void) const { return rep->is_int32 (); } - virtual int is_int64 (void) const { return rep->is_int64 (); } + int is_int64 (void) const { return rep->is_int64 (); } - virtual int is_int8 (void) const { return rep->is_int8 (); } + int is_int8 (void) const { return rep->is_int8 (); } - virtual int is_logical (void) const { return rep->is_logical (); } + int is_logical (void) const { return rep->is_logical (); } - virtual int is_numeric (void) const { return rep->is_numeric (); } + int is_numeric (void) const { return rep->is_numeric (); } - virtual int is_single (void) const { return rep->is_single (); } + int is_single (void) const { return rep->is_single (); } - virtual int is_sparse (void) const { return rep->is_sparse (); } + int is_sparse (void) const { return rep->is_sparse (); } - virtual int is_struct (void) const { return rep->is_struct (); } + int is_struct (void) const { return rep->is_struct (); } - virtual int is_uint16 (void) const { return rep->is_uint16 (); } + int is_uint16 (void) const { return rep->is_uint16 (); } - virtual int is_uint32 (void) const { return rep->is_uint32 (); } + int is_uint32 (void) const { return rep->is_uint32 (); } - virtual int is_uint64 (void) const { return rep->is_uint64 (); } + int is_uint64 (void) const { return rep->is_uint64 (); } - virtual int is_uint8 (void) const { return rep->is_uint8 (); } + int is_uint8 (void) const { return rep->is_uint8 (); } - virtual int is_logical_scalar (void) const { return rep->is_logical_scalar (); } + int is_logical_scalar (void) const { return rep->is_logical_scalar (); } - virtual int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); } + int is_logical_scalar_true (void) const { return rep->is_logical_scalar_true (); } - virtual mwSize get_m (void) const { return rep->get_m (); } + mwSize get_m (void) const { return rep->get_m (); } - virtual mwSize get_n (void) const { return rep->get_n (); } + mwSize get_n (void) const { return rep->get_n (); } - virtual mwSize *get_dimensions (void) const { return rep->get_dimensions (); } + mwSize *get_dimensions (void) const { return rep->get_dimensions (); } - virtual mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); } + mwSize get_number_of_dimensions (void) const { return rep->get_number_of_dimensions (); } - virtual void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); } + void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); } - virtual void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); } + void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); } - virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); } + void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); } - virtual mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); } + mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); } - virtual int is_empty (void) const { return get_number_of_elements () == 0; } + int is_empty (void) const { return get_number_of_elements () == 0; } const char *get_name (void) const { return name; } void set_name (const char *name_arg); - virtual mxClassID get_class_id (void) const { return rep->get_class_id (); } + mxClassID get_class_id (void) const { return rep->get_class_id (); } - virtual const char *get_class_name (void) const { return rep->get_class_name (); } + const char *get_class_name (void) const { return rep->get_class_name (); } - virtual void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); } + void set_class_name (const char *name_arg) { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); } - virtual mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); } + mxArray *get_cell (mwIndex idx) const { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); } - virtual void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); } + void set_cell (mwIndex idx, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); } - virtual double get_scalar (void) const { return rep->get_scalar (); } + double get_scalar (void) const { return rep->get_scalar (); } - virtual void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); } + void *get_data (void) const { DO_MUTABLE_METHOD (void *, get_data ()); } - virtual void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); } + void *get_imag_data (void) const { DO_MUTABLE_METHOD (void *, get_imag_data ()); } - virtual void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); } + void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); } - virtual void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); } + void set_imag_data (void *pi) { DO_VOID_MUTABLE_METHOD (set_imag_data (pi)); } - virtual mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); } + mwIndex *get_ir (void) const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); } - virtual mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); } + mwIndex *get_jc (void) const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); } - virtual mwSize get_nzmax (void) const { return rep->get_nzmax (); } + mwSize get_nzmax (void) const { return rep->get_nzmax (); } - virtual void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); } + void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); } - virtual void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); } + void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); } - virtual void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); } + void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); } - virtual int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); } + int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); } - virtual void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); } + void remove_field (int key_num) { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); } - virtual mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); } + mxArray *get_field_by_number (mwIndex index, int key_num) const { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); } - virtual void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); } + void set_field_by_number (mwIndex index, int key_num, mxArray *val) { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); } - virtual int get_number_of_fields (void) const { return rep->get_number_of_fields (); } + int get_number_of_fields (void) const { return rep->get_number_of_fields (); } - virtual const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); } + const char *get_field_name_by_number (int key_num) const { DO_MUTABLE_METHOD (const char*, get_field_name_by_number (key_num)); } - virtual int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); } + int get_field_number (const char *key) const { DO_MUTABLE_METHOD (int, get_field_number (key)); } - virtual int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); } + int get_string (char *buf, mwSize buflen) const { return rep->get_string (buf, buflen); } - virtual char *array_to_string (void) const { return rep->array_to_string (); } + char *array_to_string (void) const { return rep->array_to_string (); } - virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); } + mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const { return rep->calc_single_subscript (nsubs, subs); } - virtual size_t get_element_size (void) const { return rep->get_element_size (); } + size_t get_element_size (void) const { return rep->get_element_size (); } - virtual bool mutation_needed (void) const { return rep->mutation_needed (); } + bool mutation_needed (void) const { return rep->mutation_needed (); } - virtual mxArray *mutate (void) const { return rep->mutate (); } + mxArray *mutate (void) const { return rep->mutate (); } static void *malloc (size_t n); @@ -315,22 +486,20 @@ return retval; } - static octave_value as_octave_value (mxArray *ptr); + static octave_value as_octave_value (const mxArray *ptr); protected: - virtual octave_value as_octave_value (void) const; - - mxArray (const xmxArray&) : rep (0), name (0) { } + octave_value as_octave_value (void) const; private: - mutable mxArray *rep; + mutable mxArray_base *rep; char *name; - mxArray (mxArray *r, const char *n) - : rep (r), name (strsave (n)) { } + mxArray (mxArray_base *r, const char *n) + : rep (r), name (mxArray::strsave (n)) { } void maybe_mutate (void) const;
--- a/libinterp/interp-core/oct-obj.h +++ b/libinterp/interp-core/oct-obj.h @@ -166,4 +166,152 @@ DECLARE_OCTAVE_ALLOCATOR }; +// Make it easy to build argument lists for built-in functions or for +// returning values. + +inline octave_value_list +ovl (const octave_value& a0) +{ + octave_value_list retval; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1) +{ + octave_value_list retval; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2) +{ + octave_value_list retval; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3) +{ + octave_value_list retval; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4) +{ + octave_value_list retval; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4, const octave_value& a5) +{ + octave_value_list retval; + retval(5) = a5; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4, const octave_value& a5, + const octave_value& a6) +{ + octave_value_list retval; + retval(6) = a6; + retval(5) = a5; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4, const octave_value& a5, + const octave_value& a6, const octave_value& a7) +{ + octave_value_list retval; + retval(7) = a7; + retval(6) = a6; + retval(5) = a5; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4, const octave_value& a5, + const octave_value& a6, const octave_value& a7, + const octave_value& a8) +{ + octave_value_list retval; + retval(8) = a8; + retval(7) = a7; + retval(6) = a6; + retval(5) = a5; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + +inline octave_value_list +ovl (const octave_value& a0, const octave_value& a1, + const octave_value& a2, const octave_value& a3, + const octave_value& a4, const octave_value& a5, + const octave_value& a6, const octave_value& a7, + const octave_value& a8, const octave_value& a9) +{ + octave_value_list retval; + retval(9) = a9; + retval(8) = a8; + retval(7) = a7; + retval(6) = a6; + retval(5) = a5; + retval(4) = a4; + retval(3) = a3; + retval(2) = a2; + retval(1) = a1; + retval(0) = a0; + return retval; +} + #endif
--- a/libinterp/interp-core/oct-stream.cc +++ b/libinterp/interp-core/oct-stream.cc @@ -508,8 +508,8 @@ std::cerr << "modifier: " << elt->modifier << "\n" - << "char_class: `" << undo_string_escapes (elt->char_class) << "'\n" - << "text: `" << undo_string_escapes (elt->text) << "'\n\n"; + << "char_class: '" << undo_string_escapes (elt->char_class) << "'\n" + << "text: '" << undo_string_escapes (elt->text) << "'\n\n"; } } @@ -867,12 +867,12 @@ std::cerr << "args: " << elt->args << "\n" - << "flags: `" << elt->flags << "'\n" + << "flags: '" << elt->flags << "'\n" << "width: " << elt->fw << "\n" << "prec: " << elt->prec << "\n" - << "type: `" << elt->type << "'\n" - << "modifier: `" << elt->modifier << "'\n" - << "text: `" << undo_string_escapes (elt->text) << "'\n\n"; + << "type: '" << elt->type << "'\n" + << "modifier: '" << elt->modifier << "'\n" + << "text: '" << undo_string_escapes (elt->text) << "'\n\n"; } } @@ -1387,7 +1387,7 @@ \ tmp.resize (n) -// For a `%s' format, skip initial whitespace and then read until the +// For a '%s' format, skip initial whitespace and then read until the // next whitespace character or until WIDTH characters have been read. #define BEGIN_S_CONVERSION() \ int width = elt->width; \ @@ -2476,7 +2476,7 @@ if (elt) { - // NSA is the number of `star' args to convert. + // NSA is the number of 'star' args to convert. int nsa = (elt->fw < 0) + (elt->prec < 0);
--- a/libinterp/interp-core/oct-stream.h +++ b/libinterp/interp-core/oct-stream.h @@ -87,14 +87,14 @@ // TRUE if we are not storing the result of this conversion. bool discard; - // Type of conversion -- `d', `i', `o', `u', `x', `e', `f', `g', - // `c', `s', `p', `%', or `['. + // Type of conversion -- 'd', 'i', 'o', 'u', 'x', 'e', 'f', 'g', + // 'c', 's', 'p', '%', or '['. char type; - // A length modifier -- `h', `l', or `L'. + // A length modifier -- 'h', 'l', or 'L'. char modifier; - // The class of characters in a `[' format. + // The class of characters in a '[' format. std::string char_class; }; @@ -229,14 +229,14 @@ // Precision. int prec; - // Flags -- `-', `+', ` ', `0', or `#'. + // Flags -- '-', '+', ' ', '0', or '#'. std::string flags; - // Type of conversion -- `d', `i', `o', `x', `X', `u', `c', `s', - // `f', `e', `E', `g', `G', `p', or `%' + // Type of conversion -- 'd', 'i', 'o', 'x', 'X', 'u', 'c', 's', + // 'f', 'e', 'E', 'g', 'G', 'p', or '%' char type; - // A length modifier -- `h', `l', or `L'. + // A length modifier -- 'h', 'l', or 'L'. char modifier; };
--- a/libinterp/interp-core/oct.h +++ b/libinterp/interp-core/oct.h @@ -28,7 +28,7 @@ // config.h needs to be first because it includes #defines that can */ // affect other header files. -#include "config.h" +#include <config.h> #include "Matrix.h"
--- a/libinterp/interp-core/pt-jit.cc +++ b/libinterp/interp-core/pt-jit.cc @@ -27,13 +27,23 @@ #include <config.h> #endif -#ifdef HAVE_LLVM +#include "defun.h" +#include "ov.h" +#include "pt-all.h" +#include "pt-jit.h" +#include "symtab.h" +#include "variables.h" -#include "pt-jit.h" +bool Venable_jit_debugging = false; + +bool Venable_jit_compiler = true; + +#ifdef HAVE_LLVM #include <llvm/Analysis/CallGraph.h> #include <llvm/Analysis/Passes.h> #include <llvm/Analysis/Verifier.h> +#include <llvm/Bitcode/ReaderWriter.h> #include <llvm/LLVMContext.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/JIT.h> @@ -46,35 +56,22 @@ #include <llvm/Transforms/IPO.h> #include <llvm/Transforms/Scalar.h> -#ifdef OCTAVE_JIT_DEBUG -#include <llvm/Bitcode/ReaderWriter.h> -#endif - -#include "symtab.h" -#include "pt-all.h" - static llvm::IRBuilder<> builder (llvm::getGlobalContext ()); static llvm::LLVMContext& context = llvm::getGlobalContext (); // -------------------- jit_convert -------------------- jit_convert::jit_convert (tree &tee, jit_type *for_bounds) - : iterator_count (0), for_bounds_count (0), short_count (0), breaking (false) + : converting_function (false) { - jit_instruction::reset_ids (); - - entry_block = factory.create<jit_block> ("body"); - final_block = factory.create<jit_block> ("final"); - blocks.push_back (entry_block); - entry_block->mark_alive (); - block = entry_block; + initialize (symbol_table::current_scope ()); if (for_bounds) create_variable (next_for_bounds (false), for_bounds); visit (tee); - // FIXME: Remove if we no longer only compile loops + // breaks must have been handled by the top level loop assert (! breaking); assert (breaks.empty ()); assert (continues.empty ()); @@ -89,6 +86,91 @@ if (name.size () && name[0] != '#') final_block->append (factory.create<jit_store_argument> (var)); } + + final_block->append (factory.create<jit_return> ()); +} + +jit_convert::jit_convert (octave_user_function& fcn, + const std::vector<jit_type *>& args) + : converting_function (true) +{ + initialize (fcn.scope ()); + + tree_parameter_list *plist = fcn.parameter_list (); + tree_parameter_list *rlist = fcn.return_list (); + if (plist && plist->takes_varargs ()) + throw jit_fail_exception ("varags not supported"); + + if (rlist && (rlist->size () > 1 || rlist->takes_varargs ())) + throw jit_fail_exception ("multiple returns not supported"); + + if (plist) + { + tree_parameter_list::iterator piter = plist->begin (); + for (size_t i = 0; i < args.size (); ++i, ++piter) + { + if (piter == plist->end ()) + throw jit_fail_exception ("Too many parameter to function"); + + tree_decl_elt *elt = *piter; + std::string name = elt->name (); + create_variable (name, args[i]); + } + } + + jit_value *return_value = 0; + if (fcn.is_special_expr ()) + { + tree_expression *expr = fcn.special_expr (); + if (expr) + { + jit_variable *retvar = get_variable ("#return"); + jit_value *retval = visit (expr); + block->append (factory.create<jit_assign> (retvar, retval)); + return_value = retvar; + } + } + else + visit_statement_list (*fcn.body ()); + + // the user may use break or continue to exit the function. Because the + // function does not start as a loop, we can have one continue, one break, or + // a regular fallthrough to exit the function + if (continues.size ()) + { + assert (! continues.size ()); + finish_breaks (final_block, continues); + } + else if (breaks.size ()) + finish_breaks (final_block, breaks); + else + block->append (factory.create<jit_branch> (final_block)); + blocks.push_back (final_block); + block = final_block; + + if (! return_value && rlist && rlist->size () == 1) + { + tree_decl_elt *elt = rlist->front (); + return_value = get_variable (elt->name ()); + } + + // FIXME: We should use live range analysis to delete variables where needed. + // For now we just delete everything at the end of the function. + for (variable_map::iterator iter = vmap.begin (); iter != vmap.end (); ++iter) + { + if (iter->second != return_value) + { + jit_call *call; + call = factory.create<jit_call> (&jit_typeinfo::destroy, + iter->second); + final_block->append (call); + } + } + + if (return_value) + final_block->append (factory.create<jit_return> (return_value)); + else + final_block->append (factory.create<jit_return> ()); } void @@ -243,8 +325,6 @@ vmap[iter_name] = iterator; jit_block *body = factory.create<jit_block> ("for_body"); - blocks.push_back (body); - jit_block *tail = factory.create<jit_block> ("for_tail"); // do control expression, iter init, and condition check in prev_block (block) @@ -261,6 +341,8 @@ iterator); block->append (check); block->append (factory.create<jit_cond_branch> (check, body, tail)); + + blocks.push_back (body); block = body; // compute the syntactical iterator @@ -353,7 +435,12 @@ result = block->append (factory.create<jit_magic_end> (end_context)); } else - result = get_variable (ti.name ()); + { + jit_variable *var = get_variable (ti.name ()); + jit_instruction *instr; + instr = factory.create<jit_call> (&jit_typeinfo::grab, var); + result = block->append (instr); + } } void @@ -452,7 +539,7 @@ void jit_convert::visit_index_expression (tree_index_expression& exp) { - result = resolve (jit_typeinfo::paren_subsref (), exp); + result = resolve (exp); } void @@ -483,7 +570,7 @@ jit_convert::visit_constant (tree_constant& tc) { octave_value v = tc.rvalue1 (); - if (v.is_real_scalar () && v.is_double_type ()) + if (v.is_real_scalar () && v.is_double_type () && ! v.is_complex_type ()) { double dv = v.double_value (); result = factory.create<jit_const_scalar> (dv); @@ -526,7 +613,7 @@ if (etype == octave_value::op_incr || etype == octave_value::op_decr) { - jit_value *ret = create_checked (&jit_typeinfo::copy, operandv); + jit_value *ret = create_checked (&jit_typeinfo::grab, operandv); do_assign (operand, result); result = ret; } @@ -708,6 +795,23 @@ throw jit_fail_exception (); } +void +jit_convert::initialize (symbol_table::scope_id s) +{ + scope = s; + iterator_count = 0; + for_bounds_count = 0; + short_count = 0; + breaking = false; + jit_instruction::reset_ids (); + + entry_block = factory.create<jit_block> ("body"); + final_block = factory.create<jit_block> ("final"); + blocks.push_back (entry_block); + entry_block->mark_alive (); + block = entry_block; +} + jit_call * jit_convert::create_checked_impl (jit_call *ret) { @@ -738,18 +842,42 @@ if (ret) return ret; - octave_value val = symbol_table::find (vname); - jit_type *type = jit_typeinfo::type_of (val); - return create_variable (vname, type); + symbol_table::symbol_record record = symbol_table::find_symbol (vname, scope); + if (record.is_persistent () || record.is_global ()) + throw jit_fail_exception ("Persistent and global not yet supported"); + + if (converting_function) + return create_variable (vname, jit_typeinfo::get_any (), false); + else + { + octave_value val = record.varval (); + jit_type *type = jit_typeinfo::type_of (val); + bounds.push_back (type_bound (type, vname)); + + return create_variable (vname, type); + } } jit_variable * -jit_convert::create_variable (const std::string& vname, jit_type *type) +jit_convert::create_variable (const std::string& vname, jit_type *type, + bool isarg) { jit_variable *var = factory.create<jit_variable> (vname); - jit_extract_argument *extract; - extract = factory.create<jit_extract_argument> (type, var); - entry_block->prepend (extract); + + if (isarg) + { + jit_extract_argument *extract; + extract = factory.create<jit_extract_argument> (type, var); + entry_block->prepend (extract); + } + else + { + jit_call *init = factory.create<jit_call> (&jit_typeinfo::create_undef); + jit_assign *assign = factory.create<jit_assign> (var, init); + entry_block->prepend (assign); + entry_block->prepend (init); + } + return vmap[vname] = var; } @@ -764,8 +892,8 @@ } jit_instruction * -jit_convert::resolve (const jit_operation& fres, tree_index_expression& exp, - jit_value *extra_arg) +jit_convert::resolve (tree_index_expression& exp, jit_value *extra_arg, + bool lhs) { std::string type = exp.type_tags (); if (! (type.size () == 1 && type[0] == '(')) @@ -773,7 +901,8 @@ std::list<tree_argument_list *> args = exp.arg_lists (); if (args.size () != 1) - throw jit_fail_exception ("Bad number of arguments in tree_index_expression"); + throw jit_fail_exception ("Bad number of arguments in " + "tree_index_expression"); tree_argument_list *arg_list = args.front (); if (! arg_list) @@ -783,7 +912,16 @@ throw jit_fail_exception ("Empty arg_list"); tree_expression *tree_object = exp.expression (); - jit_value *object = visit (tree_object); + jit_value *object; + if (lhs) + { + tree_identifier *id = dynamic_cast<tree_identifier *> (tree_object); + if (! id) + throw jit_fail_exception ("expected identifier"); + object = get_variable (id->name ()); + } + else + object = visit (tree_object); size_t narg = arg_list->size (); tree_argument_list::iterator iter = arg_list->begin (); @@ -805,6 +943,9 @@ if (extra_arg) call_args[call_args.size () - 1] = extra_arg; + const jit_operation& fres = lhs ? jit_typeinfo::paren_subsasgn () + : jit_typeinfo::paren_subsref (); + return create_checked (fres, call_args); } @@ -819,8 +960,7 @@ else if (tree_index_expression *idx = dynamic_cast<tree_index_expression *> (exp)) { - jit_value *new_object = resolve (jit_typeinfo::paren_subsasgn (), *idx, - rhs); + jit_value *new_object = resolve (*idx, rhs, true); do_assign (idx->expression (), new_object, true); // FIXME: Will not work for values that must be release/grabed @@ -873,10 +1013,12 @@ // -------------------- jit_convert_llvm -------------------- llvm::Function * -jit_convert_llvm::convert (llvm::Module *module, - const jit_block_list& blocks, - const std::list<jit_value *>& constants) +jit_convert_llvm::convert_loop (llvm::Module *module, + const jit_block_list& blocks, + const std::list<jit_value *>& constants) { + converting_function = false; + // for now just init arguments from entry, later we will have to do something // more interesting jit_block *entry_block = blocks.front (); @@ -909,44 +1051,7 @@ arguments[argument_vec[i].first] = loaded_arg; } - std::list<jit_block *>::const_iterator biter; - for (biter = blocks.begin (); biter != blocks.end (); ++biter) - { - jit_block *jblock = *biter; - llvm::BasicBlock *block = llvm::BasicBlock::Create (context, - jblock->name (), - function); - jblock->stash_llvm (block); - } - - jit_block *first = *blocks.begin (); - builder.CreateBr (first->to_llvm ()); - - // constants aren't in the IR, we visit those first - for (std::list<jit_value *>::const_iterator iter = constants.begin (); - iter != constants.end (); ++iter) - if (! isa<jit_instruction> (*iter)) - visit (*iter); - - // convert all instructions - for (biter = blocks.begin (); biter != blocks.end (); ++biter) - visit (*biter); - - // now finish phi nodes - for (biter = blocks.begin (); biter != blocks.end (); ++biter) - { - jit_block& block = **biter; - for (jit_block::iterator piter = block.begin (); - piter != block.end () && isa<jit_phi> (*piter); ++piter) - { - jit_instruction *phi = *piter; - finish_phi (static_cast<jit_phi *> (phi)); - } - } - - jit_block *last = blocks.back (); - builder.SetInsertPoint (last->to_llvm ()); - builder.CreateRetVoid (); + convert (blocks, constants); } catch (const jit_fail_exception& e) { function->eraseFromParent (); @@ -956,6 +1061,92 @@ return function; } + +jit_function +jit_convert_llvm::convert_function (llvm::Module *module, + const jit_block_list& blocks, + const std::list<jit_value *>& constants, + octave_user_function& fcn, + const std::vector<jit_type *>& args) +{ + converting_function = true; + + jit_block *final_block = blocks.back (); + jit_return *ret = dynamic_cast<jit_return *> (final_block->back ()); + assert (ret); + + creating = jit_function (module, jit_convention::internal, + "foobar", ret->result_type (), args); + function = creating.to_llvm (); + + try + { + prelude = creating.new_block ("prelude"); + builder.SetInsertPoint (prelude); + + tree_parameter_list *plist = fcn.parameter_list (); + if (plist) + { + tree_parameter_list::iterator piter = plist->begin (); + tree_parameter_list::iterator pend = plist->end (); + for (size_t i = 0; i < args.size () && piter != pend; ++i, ++piter) + { + tree_decl_elt *elt = *piter; + std::string arg_name = elt->name (); + arguments[arg_name] = creating.argument (builder, i); + } + } + + convert (blocks, constants); + } catch (const jit_fail_exception& e) + { + function->eraseFromParent (); + throw; + } + + return creating; +} + +void +jit_convert_llvm::convert (const jit_block_list& blocks, + const std::list<jit_value *>& constants) +{ + std::list<jit_block *>::const_iterator biter; + for (biter = blocks.begin (); biter != blocks.end (); ++biter) + { + jit_block *jblock = *biter; + llvm::BasicBlock *block = llvm::BasicBlock::Create (context, + jblock->name (), + function); + jblock->stash_llvm (block); + } + + jit_block *first = *blocks.begin (); + builder.CreateBr (first->to_llvm ()); + + // constants aren't in the IR, we visit those first + for (std::list<jit_value *>::const_iterator iter = constants.begin (); + iter != constants.end (); ++iter) + if (! isa<jit_instruction> (*iter)) + visit (*iter); + + // convert all instructions + for (biter = blocks.begin (); biter != blocks.end (); ++biter) + visit (*biter); + + // now finish phi nodes + for (biter = blocks.begin (); biter != blocks.end (); ++biter) + { + jit_block& block = **biter; + for (jit_block::iterator piter = block.begin (); + piter != block.end () && isa<jit_phi> (*piter); ++piter) + { + jit_instruction *phi = *piter; + finish_phi (static_cast<jit_phi *> (phi)); + } + } +} + void jit_convert_llvm::finish_phi (jit_phi *phi) { @@ -1064,10 +1255,16 @@ { llvm::Value *arg = arguments[extract.name ()]; assert (arg); - arg = builder.CreateLoad (arg); - const jit_function& ol = extract.overload (); - extract.stash_llvm (ol.call (builder, arg)); + if (converting_function) + extract.stash_llvm (arg); + else + { + arg = builder.CreateLoad (arg); + + const jit_function& ol = extract.overload (); + extract.stash_llvm (ol.call (builder, arg)); + } } void @@ -1080,6 +1277,22 @@ } void +jit_convert_llvm::visit (jit_return& ret) +{ + jit_value *res = ret.result (); + + if (converting_function) + creating.do_return (builder, res->to_llvm (), false); + else + { + if (res) + builder.CreateRet (res->to_llvm ()); + else + builder.CreateRetVoid (); + } +} + +void jit_convert_llvm::visit (jit_phi& phi) { // we might not have converted all incoming branches, so we don't @@ -1114,13 +1327,6 @@ if (assign.artificial ()) return; - if (isa<jit_assign_base> (new_value)) - { - const jit_function& ol = jit_typeinfo::get_grab (new_value->type ()); - if (ol.valid ()) - assign.stash_llvm (ol.call (builder, new_value)); - } - jit_value *overwrite = assign.overwrite (); if (isa<jit_assign_base> (overwrite)) { @@ -1285,17 +1491,16 @@ { jit_phi *phi = static_cast<jit_phi *> (*iter); jit_variable *var = phi->dest (); + ++iter; + if (var->has_top ()) - { - phi->add_incomming (&ablock, var->top ()); - ++iter; - } + phi->add_incomming (&ablock, var->top ()); else { // temporaries may have extranious phi nodes which can be removed assert (! phi->use_count ()); assert (var->name ().size () && var->name ()[0] == '#'); - iter = finish->remove (iter); + phi->remove (); } } } @@ -1522,44 +1727,27 @@ bool tree_jit::execute (tree_simple_for_command& cmd, const octave_value& bounds) { - const size_t MIN_TRIP_COUNT = 1000; - - size_t tc = trip_count (bounds); - if (! tc || ! initialize ()) - return false; - - jit_info::vmap extra_vars; - extra_vars["#for_bounds0"] = &bounds; - - jit_info *info = cmd.get_info (); - if (! info || ! info->match (extra_vars)) - { - if (tc < MIN_TRIP_COUNT) - return false; - - delete info; - info = new jit_info (*this, cmd, bounds); - cmd.stash_info (info); - } - - return info->execute (extra_vars); + return instance ().do_execute (cmd, bounds); } bool tree_jit::execute (tree_while_command& cmd) { - if (! initialize ()) - return false; + return instance ().do_execute (cmd); +} - jit_info *info = cmd.get_info (); - if (! info || ! info->match ()) - { - delete info; - info = new jit_info (*this, cmd); - cmd.stash_info (info); - } +bool +tree_jit::execute (octave_user_function& fcn, const octave_value_list& args, + octave_value_list& retval) +{ + return instance ().do_execute (fcn, args, retval); +} - return info->execute (); +tree_jit& +tree_jit::instance (void) +{ + static tree_jit ret; + return ret; } bool @@ -1599,6 +1787,67 @@ return true; } +bool +tree_jit::do_execute (tree_simple_for_command& cmd, const octave_value& bounds) +{ + const size_t MIN_TRIP_COUNT = 1000; + + size_t tc = trip_count (bounds); + if (! tc || ! initialize ()) + return false; + + jit_info::vmap extra_vars; + extra_vars["#for_bounds0"] = &bounds; + + jit_info *info = cmd.get_info (); + if (! info || ! info->match (extra_vars)) + { + if (tc < MIN_TRIP_COUNT) + return false; + + delete info; + info = new jit_info (*this, cmd, bounds); + cmd.stash_info (info); + } + + return info->execute (extra_vars); +} + +bool +tree_jit::do_execute (tree_while_command& cmd) +{ + if (! initialize ()) + return false; + + jit_info *info = cmd.get_info (); + if (! info || ! info->match ()) + { + delete info; + info = new jit_info (*this, cmd); + cmd.stash_info (info); + } + + return info->execute (); +} + +bool +tree_jit::do_execute (octave_user_function& fcn, const octave_value_list& args, + octave_value_list& retval) +{ + if (! initialize ()) + return false; + + jit_function_info *info = fcn.get_info (); + if (! info || ! info->match (args)) + { + delete info; + info = new jit_function_info (*this, fcn, args); + fcn.stash_info (info); + } + + return info->execute (args, retval); +} + size_t tree_jit::trip_count (const octave_value& bounds) const { @@ -1616,15 +1865,177 @@ void tree_jit::optimize (llvm::Function *fn) { + if (Venable_jit_debugging) + llvm::verifyModule (*module); + module_pass_manager->run (*module); pass_manager->run (*fn); -#ifdef OCTAVE_JIT_DEBUG - std::string error; - llvm::raw_fd_ostream fout ("test.bc", error, - llvm::raw_fd_ostream::F_Binary); - llvm::WriteBitcodeToFile (module, fout); -#endif + if (Venable_jit_debugging) + { + std::string error; + llvm::raw_fd_ostream fout ("test.bc", error, + llvm::raw_fd_ostream::F_Binary); + llvm::WriteBitcodeToFile (module, fout); + } +} + +// -------------------- jit_function_info -------------------- +jit_function_info::jit_function_info (tree_jit& tjit, + octave_user_function& fcn, + const octave_value_list& ov_args) + : argument_types (ov_args.length ()), function (0) +{ + size_t nargs = ov_args.length (); + for (size_t i = 0; i < nargs; ++i) + argument_types[i] = jit_typeinfo::type_of (ov_args(i)); + + jit_function raw_fn; + jit_function wrapper; + + try + { + jit_convert conv (fcn, argument_types); + jit_infer infer (conv.get_factory (), conv.get_blocks (), + conv.get_variable_map ()); + infer.infer (); + + if (Venable_jit_debugging) + { + jit_block_list& blocks = infer.get_blocks (); + jit_block *entry_block = blocks.front (); + entry_block->label (); + std::cout << "-------------------- Compiling function "; + std::cout << "--------------------\n"; + + tree_print_code tpc (std::cout); + tpc.visit_octave_user_function_header (fcn); + tpc.visit_statement_list (*fcn.body ()); + tpc.visit_octave_user_function_trailer (fcn); + blocks.print (std::cout, "octave jit ir"); + } + + jit_factory& factory = conv.get_factory (); + llvm::Module *module = tjit.get_module (); + jit_convert_llvm to_llvm; + raw_fn = to_llvm.convert_function (module, infer.get_blocks (), + factory.constants (), fcn, + argument_types); + + if (Venable_jit_debugging) + { + std::cout << "-------------------- raw function "; + std::cout << "--------------------\n"; + std::cout << *raw_fn.to_llvm () << std::endl; + llvm::verifyFunction (*raw_fn.to_llvm ()); + } + + std::string wrapper_name = fcn.name () + "_wrapper"; + jit_type *any_t = jit_typeinfo::get_any (); + std::vector<jit_type *> wrapper_args (1, jit_typeinfo::get_any_ptr ()); + wrapper = jit_function (module, jit_convention::internal, wrapper_name, + any_t, wrapper_args); + + llvm::BasicBlock *wrapper_body = wrapper.new_block (); + builder.SetInsertPoint (wrapper_body); + + llvm::Value *wrapper_arg = wrapper.argument (builder, 0); + std::vector<llvm::Value *> raw_args (nargs); + for (size_t i = 0; i < nargs; ++i) + { + llvm::Value *arg; + arg = builder.CreateConstInBoundsGEP1_32 (wrapper_arg, i); + arg = builder.CreateLoad (arg); + + jit_type *arg_type = argument_types[i]; + const jit_function& cast = jit_typeinfo::cast (arg_type, any_t); + raw_args[i] = cast.call (builder, arg); + } + + llvm::Value *result = raw_fn.call (builder, raw_args); + if (raw_fn.result ()) + { + jit_type *raw_result_t = raw_fn.result (); + const jit_function& cast = jit_typeinfo::cast (any_t, raw_result_t); + result = cast.call (builder, result); + } + else + { + llvm::Value *zero = builder.getInt32 (0); + result = builder.CreateBitCast (zero, any_t->to_llvm ()); + } + + wrapper.do_return (builder, result); + + llvm::Function *llvm_function = wrapper.to_llvm (); + tjit.optimize (llvm_function); + + if (Venable_jit_debugging) + { + std::cout << "-------------------- optimized and wrapped "; + std::cout << "--------------------\n"; + std::cout << *llvm_function << std::endl; + llvm::verifyFunction (*llvm_function); + } + + llvm::ExecutionEngine* engine = tjit.get_engine (); + void *void_fn = engine->getPointerToFunction (llvm_function); + function = reinterpret_cast<jited_function> (void_fn); + } + catch (const jit_fail_exception& e) + { + argument_types.clear (); + + if (Venable_jit_debugging) + { + if (e.known ()) + std::cout << "jit fail: " << e.what () << std::endl; + } + + wrapper.erase (); + raw_fn.erase (); + } +} + +bool +jit_function_info::execute (const octave_value_list& ov_args, + octave_value_list& retval) const +{ + if (! function) + return false; + + // TODO figure out a way to delete ov_args so we avoid duplicating refcount + size_t nargs = ov_args.length (); + std::vector<octave_base_value *> args (nargs); + for (size_t i = 0; i < nargs; ++i) + { + octave_base_value *obv = ov_args(i).internal_rep (); + obv->grab (); + args[i] = obv; + } + + octave_base_value *ret = function (&args[0]); + if (ret) + retval(0) = octave_value (ret); + + return true; +} + +bool +jit_function_info::match (const octave_value_list& ov_args) const +{ + if (! function) + return true; + + size_t nargs = ov_args.length (); + if (nargs != argument_types.size ()) + return false; + + for (size_t i = 0; i < nargs; ++i) + if (jit_typeinfo::type_of (ov_args(i)) != argument_types[i]) + return false; + + return true; } // -------------------- jit_info -------------------- @@ -1708,49 +2119,51 @@ conv.get_variable_map ()); infer.infer (); -#ifdef OCTAVE_JIT_DEBUG - jit_block *entry_block = infer.get_blocks ().front (); - entry_block->label (); - std::cout << "-------------------- Compiling tree --------------------\n"; - std::cout << tee.str_print_code () << std::endl; - entry_block->print (std::cout, "octave jit ir"); -#endif + + if (Venable_jit_debugging) + { + jit_block_list& blocks = infer.get_blocks (); + jit_block *entry_block = blocks.front (); + entry_block->label (); + std::cout << "-------------------- Compiling tree --------------------\n"; + std::cout << tee.str_print_code () << std::endl; + blocks.print (std::cout, "octave jit ir"); + } jit_factory& factory = conv.get_factory (); jit_convert_llvm to_llvm; - llvm_function = to_llvm.convert (tjit.get_module (), infer.get_blocks (), - factory.constants ()); + llvm_function = to_llvm.convert_loop (tjit.get_module (), + infer.get_blocks (), + factory.constants ()); arguments = to_llvm.get_arguments (); bounds = conv.get_bounds (); } catch (const jit_fail_exception& e) { -#ifdef OCTAVE_JIT_DEBUG - if (e.known ()) - std::cout << "jit fail: " << e.what () << std::endl; -#endif + if (Venable_jit_debugging) + { + if (e.known ()) + std::cout << "jit fail: " << e.what () << std::endl; + } } if (llvm_function) { -#ifdef OCTAVE_JIT_DEBUG - std::cout << "-------------------- llvm ir --------------------"; - llvm::raw_os_ostream llvm_cout (std::cout); - function->print (llvm_cout); - std::cout << std::endl; - llvm::verifyFunction (*function); -#endif + if (Venable_jit_debugging) + { + std::cout << "-------------------- llvm ir --------------------"; + std::cout << *llvm_function << std::endl; + llvm::verifyFunction (*llvm_function); + } tjit.optimize (llvm_function); -#ifdef OCTAVE_JIT_DEBUG - std::cout << "-------------------- optimized llvm ir " - << "--------------------\n"; - llvm::raw_os_ostream llvm_cout (std::cout); - llvm_function->print (llvm_cout); - llvm_cout.flush (); - std::cout << std::endl; -#endif + if (Venable_jit_debugging) + { + std::cout << "-------------------- optimized llvm ir " + << "--------------------\n"; + std::cout << *llvm_function << std::endl; + } void *void_fn = engine->getPointerToFunction (llvm_function); function = reinterpret_cast<jited_function> (void_fn); @@ -1767,6 +2180,48 @@ #endif +DEFUN (enable_jit_debugging, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} enable_jit_debugging ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} enable_jit_debugging (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} enable_jit_debugging (@var{new_val}, \"local\")\n\ +Query or set the internal variable that determines whether\n\ +debugging/tracing is enabled for Octave's JIT compiler.\n\ +\n\ +When called from inside a function with the \"local\" option, the variable is\n\ +changed locally for the function and any subroutines it calls. The original\n\ +variable value is restored when exiting the function.\n\ +@seealso{enable_jit_compiler}\n\ +@end deftypefn") +{ +#if defined (HAVE_LLVM) + return SET_INTERNAL_VARIABLE (enable_jit_debugging); +#else + warning ("enable_jit_debugging: JIT compiling not available in this version of Octave"); + return octave_value (); +#endif +} + +DEFUN (enable_jit_compiler, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} enable_jit_compiler ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} enable_jit_compiler (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} enable_jit_compiler (@var{new_val}, \"local\")\n\ +Query or set the internal variable that enables Octave's JIT compiler.\n\ +\n\ +When called from inside a function with the \"local\" option, the variable is\n\ +changed locally for the function and any subroutines it calls. The original\n\ +variable value is restored when exiting the function.\n\ +@seealso{enable_jit_debugging}\n\ +@end deftypefn") +{ +#if defined (HAVE_LLVM) + return SET_INTERNAL_VARIABLE (enable_jit_compiler); +#else + warning ("enable_jit_compiler: JIT compiling not available in this version of Octave"); + return octave_value (); +#endif +} /* Test some simple cases that compile. @@ -2012,4 +2467,69 @@ %!error test_compute_idom () +%!function x = test_overload (a) +%! while 1 +%! x = a; +%! break; +%! endwhile +%!endfunction + +%!assert (test_overload (1), 1); +%!assert (test_overload ([1 2]), [1 2]); + +%!function a = bubble (a = [3 2 1]) +%! swapped = 1; +%! n = length (a); +%! while (swapped) +%! swapped = 0; +%! for i = 1:n-1 +%! if a(i) > a(i + 1) +%! swapped = 1; +%! temp = a(i); +%! a(i) = a(i + 1); +%! a(i + 1) = temp; +%! endif +%! endfor +%! endwhile +%!endfunction + +%!assert (bubble (), [1 2 3]); + +%!test +%! a = 0; +%! b = 1; +%! for i=1:1e3 +%! for j=1:2 +%! a = a + b; +%! endfor +%! endfor +%! assert (a, 2000); +%! assert (b, 1); + +%!test +%! a = [1+1i 1+2i]; +%! b = 0; +%! while 1 +%! b = a(1); +%! break; +%! endwhile +%! assert (b, a(1)); + +%!function test_undef () +%! for i=1:1e7 +%! XXX; +%! endfor +%!endfunction + +%!error <undefined near> (test_undef); + +%!shared id +%! id = @(x) x; + +%!assert (id (1), 1); +%!assert (id (1+1i), 1+1i) +%!assert (id (1, 2), 1) +%!error <undefined> (id ()) + + */
--- a/libinterp/interp-core/pt-jit.h +++ b/libinterp/interp-core/pt-jit.h @@ -26,8 +26,10 @@ #ifdef HAVE_LLVM #include "jit-ir.h" +#include "pt-walk.h" +#include "symtab.h" -#include "pt-walk.h" +class octave_value_list; // Convert from the parse tree (AST) to the low level Octave IR. class @@ -40,6 +42,8 @@ jit_convert (tree &tee, jit_type *for_bounds = 0); + jit_convert (octave_user_function& fcn, const std::vector<jit_type *>& args); + #define DECL_ARG(n) const ARG ## n& arg ## n #define JIT_CREATE_CHECKED(N) \ template <OCT_MAKE_DECL_LIST (typename, ARG, N)> \ @@ -156,6 +160,11 @@ std::vector<std::pair<std::string, bool> > arguments; type_bound_vector bounds; + bool converting_function; + + // the scope of the function we are converting, or the current scope + symbol_table::scope_id scope; + jit_factory factory; // used instead of return values from visit_* functions @@ -179,6 +188,8 @@ variable_map vmap; + void initialize (symbol_table::scope_id s); + jit_call *create_checked_impl (jit_call *ret); // get an existing vairable. If the variable does not exist, it will not be @@ -191,7 +202,8 @@ // create a variable of the given name and given type. Will also insert an // extract statement - jit_variable *create_variable (const std::string& vname, jit_type *type); + jit_variable *create_variable (const std::string& vname, jit_type *type, + bool isarg = true); // The name of the next for loop iterator. If inc is false, then the iterator // counter will not be incremented. @@ -206,9 +218,8 @@ std::string next_name (const char *prefix, size_t& count, bool inc); - jit_instruction *resolve (const jit_operation& fres, - tree_index_expression& exp, - jit_value *extra_arg = 0); + jit_instruction *resolve (tree_index_expression& exp, + jit_value *extra_arg = 0, bool lhs = false); jit_value *do_assign (tree_expression *exp, jit_value *rhs, bool artificial = false); @@ -234,10 +245,17 @@ jit_convert_llvm : public jit_ir_walker { public: - llvm::Function *convert (llvm::Module *module, - const jit_block_list& blocks, - const std::list<jit_value *>& constants); + llvm::Function *convert_loop (llvm::Module *module, + const jit_block_list& blocks, + const std::list<jit_value *>& constants); + jit_function convert_function (llvm::Module *module, + const jit_block_list& blocks, + const std::list<jit_value *>& constants, + octave_user_function& fcn, + const std::vector<jit_type *>& args); + + // arguments to the llvm::Function for loops const std::vector<std::pair<std::string, bool> >& get_arguments(void) const { return argument_vec; } @@ -248,13 +266,25 @@ #undef JIT_METH private: + // name -> argument index (used for compiling functions) + std::map<std::string, int> argument_index; + std::vector<std::pair<std::string, bool> > argument_vec; - // name -> llvm argument + // name -> llvm argument (used for compiling loops) std::map<std::string, llvm::Value *> arguments; + + bool converting_function; + + // only used if we are converting a function + jit_function creating; + llvm::Function *function; llvm::BasicBlock *prelude; + void convert (const jit_block_list& blocks, + const std::list<jit_value *>& constants); + void finish_phi (jit_phi *phi); void visit (jit_value *jvalue) @@ -320,13 +350,15 @@ tree_jit { public: - tree_jit (void); - ~tree_jit (void); - bool execute (tree_simple_for_command& cmd, const octave_value& bounds); + static bool execute (tree_simple_for_command& cmd, + const octave_value& bounds); - bool execute (tree_while_command& cmd); + static bool execute (tree_while_command& cmd); + + static bool execute (octave_user_function& fcn, const octave_value_list& args, + octave_value_list& retval); llvm::ExecutionEngine *get_engine (void) const { return engine; } @@ -334,8 +366,19 @@ void optimize (llvm::Function *fn); private: + tree_jit (void); + + static tree_jit& instance (void); + bool initialize (void); + bool do_execute (tree_simple_for_command& cmd, const octave_value& bounds); + + bool do_execute (tree_while_command& cmd); + + bool do_execute (octave_user_function& fcn, const octave_value_list& args, + octave_value_list& retval); + size_t trip_count (const octave_value& bounds) const; llvm::Module *module; @@ -345,6 +388,24 @@ }; class +jit_function_info +{ +public: + jit_function_info (tree_jit& tjit, octave_user_function& fcn, + const octave_value_list& ov_args); + + bool execute (const octave_value_list& ov_args, + octave_value_list& retval) const; + + bool match (const octave_value_list& ov_args) const; +private: + typedef octave_base_value *(*jited_function)(octave_base_value**); + + std::vector<jit_type *> argument_types; + jited_function function; +}; + +class jit_info { public: @@ -378,4 +439,11 @@ }; #endif + +// If TRUE, enable JIT compiler debugging/tracing. +extern bool Venable_jit_debugging; + +// If TRUE, enable JIT compiler. +extern bool Venable_jit_compiler; + #endif
--- a/libinterp/interp-core/sparse-xpow.cc +++ b/libinterp/interp-core/sparse-xpow.cc @@ -230,6 +230,29 @@ // small real part. But perhaps that's really a problem with the math // library... +// Handle special case of scalar-sparse-matrix .^ sparse-matrix. +// Forwarding to the scalar elem_xpow function and then converting the +// result back to a sparse matrix is a bit wasteful but it does not +// seem worth the effort to optimize -- how often does this case come up +// in practice? + +template <class S, class SM> +inline octave_value +scalar_xpow (const S& a, const SM& b) +{ + octave_value val = elem_xpow (a, b); + + if (val.is_complex_type ()) + return SparseComplexMatrix (val.complex_matrix_value ()); + else + return SparseMatrix (val.matrix_value ()); +} + +/* +%!assert (sparse (2) .^ [3, 4], sparse ([8, 16])); +%!assert (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16])); +*/ + // -*- 1 -*- octave_value elem_xpow (double a, const SparseMatrix& b) @@ -400,6 +423,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -502,6 +528,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -642,6 +671,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc); @@ -710,6 +742,9 @@ octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); + if (a.numel () == 1 && b.numel () > 1) + return scalar_xpow (a(0), b); + if (nr != b_nr || nc != b_nc) { gripe_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
--- a/libinterp/interp-core/txt-eng-ft.cc +++ b/libinterp/interp-core/txt-eng-ft.cc @@ -45,7 +45,7 @@ gripe_missing_glyph (char c) { warning_with_id ("Octave:missing-glyph", - "ft_render: skipping missing glyph for character `%c'", + "ft_render: skipping missing glyph for character '%c'", c); } @@ -53,7 +53,7 @@ gripe_glyph_render (char c) { warning_with_id ("Octave:glyph-render", - "ft_render: unable to render glyph for character `%c'", + "ft_render: unable to render glyph for character '%c'", c); } @@ -136,7 +136,7 @@ // FIXME -- Skip the call to FcFini because it can trigger the // assertion // - // octave: fccache.c:507: FcCacheFini: Assertion `fcCacheChains[i] == ((void *)0)' failed. + // octave: fccache.c:507: FcCacheFini: Assertion 'fcCacheChains[i] == ((void *)0)' failed. // // if (fontconfig_initialized) // FcFini (); @@ -298,7 +298,7 @@ } break; default: - ::error ("ft_render: invalid mode `%d'", mode); + ::error ("ft_render: invalid mode '%d'", mode); break; } }
--- a/libinterp/interp-core/unwind-prot.cc +++ b/libinterp/interp-core/unwind-prot.cc @@ -25,12 +25,8 @@ #include <config.h> #endif -#include <cstddef> -#include <cstring> - #include "error.h" #include "unwind-prot.h" -#include "utils.h" void unwind_protect_safe::gripe_exception (void) {
--- a/libinterp/interp-core/unwind-prot.h +++ b/libinterp/interp-core/unwind-prot.h @@ -24,289 +24,74 @@ #if !defined (octave_unwind_prot_h) #define octave_unwind_prot_h 1 -#include <cstddef> - -#include <string> +#include <stack> #include <memory> -// This class allows registering cleanup actions. +#include "action-container.h" + class OCTINTERP_API -unwind_protect +unwind_protect : public action_container { public: - // A generic unwind_protect element. Knows how to run itself and discard itself. - // Also, contains a pointer to the next element. - class elem - { - elem *next; - - public: - elem (void) : next (0) { } - - virtual void run (void) { } - - virtual ~elem (void) { } - - friend class unwind_protect; - - private: - - // No copying! - - elem (const elem&); - - elem& operator = (const elem&); - }; - - // An element that merely runs a void (*)(void) function. - - class fcn_elem : public elem - { - public: - fcn_elem (void (*fptr) (void)) - : e_fptr (fptr) { } + unwind_protect (void) : lifo () { } - void run (void) { e_fptr (); } - - private: - void (*e_fptr) (void); - }; - - // An element that stores a variable of type T along with a void (*) (T) - // function pointer, and calls the function with the parameter. - - template <class T> - class fcn_arg_elem : public elem - { - public: - fcn_arg_elem (void (*fcn) (T), T arg) - : e_fcn (fcn), e_arg (arg) { } + // Destructor should not raise an exception, so all actions + // registered should be exception-safe (but setting error_state is + // allowed). If you're not sure, see unwind_protect_safe. - void run (void) { e_fcn (e_arg); } - - private: - - // No copying! - - fcn_arg_elem (const fcn_arg_elem&); - - fcn_arg_elem& operator = (const fcn_arg_elem&); - - void (*e_fcn) (T); - T e_arg; - }; - - // An element that stores a variable of type T along with a void (*) (const T&) - // function pointer, and calls the function with the parameter. + ~unwind_protect (void) { run (); } - template <class T> - class fcn_crefarg_elem : public elem + virtual void add (elem *new_elem) { - public: - fcn_crefarg_elem (void (*fcn) (const T&), T arg) - : e_fcn (fcn), e_arg (arg) { } - - void run (void) { e_fcn (e_arg); } - - private: - void (*e_fcn) (const T&); - T e_arg; - }; - - // An element for calling a member function. - - template <class T> - class method_elem : public elem - { - public: - method_elem (T *obj, void (T::*method) (void)) - : e_obj (obj), e_method (method) { } - - void run (void) { (e_obj->*e_method) (); } - - private: - - T *e_obj; - void (T::*e_method) (void); - - // No copying! - - method_elem (const method_elem&); + lifo.push (new_elem); + } - method_elem operator = (const method_elem&); - }; - - // An element that stores arbitrary variable, and restores it. - - template <class T> - class restore_var_elem : public elem + void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED { - public: - restore_var_elem (T& ref, const T& val) - : e_ptr (&ref), e_val (val) { } - - void run (void) { *e_ptr = e_val; } - - private: + add (new fcn_arg_elem<void *> (fcn, ptr)); + } - // No copying! - - restore_var_elem (const restore_var_elem&); - - restore_var_elem& operator = (const restore_var_elem&); - - T *e_ptr, e_val; - }; + operator bool (void) const { return ! empty (); } - // Deletes a class allocated using new. - - template <class T> - class delete_ptr_elem : public elem - { - public: - delete_ptr_elem (T *ptr) - : e_ptr (ptr) { } + void run_top (void) GCC_ATTR_DEPRECATED { run_first (); } - void run (void) { delete e_ptr; } - - private: - - T *e_ptr; - - // No copying! - - delete_ptr_elem (const delete_ptr_elem&); - - delete_ptr_elem operator = (const delete_ptr_elem&); - }; - - unwind_protect (void) : head () { } - - void add (elem *new_elem) - { - new_elem->next = head; - head = new_elem; - } - - // For backward compatibility. - void add (void (*fcn) (void *), void *ptr = 0) - { - add (new fcn_arg_elem<void *> (fcn, ptr)); - } + void run_first (void) + { + if (! empty ()) + { + // No leak on exception! + std::auto_ptr<elem> ptr (lifo.top ()); + lifo.pop (); + ptr->run (); + } + } - // Call to void func (void). - void add_fcn (void (*fcn) (void)) - { - add (new fcn_elem (fcn)); - } - - // Call to void func (T). - template <class T> - void add_fcn (void (*action) (T), T val) - { - add (new fcn_arg_elem<T> (action, val)); - } + void run_top (int num) GCC_ATTR_DEPRECATED { run (num); } - // Call to void func (const T&). - template <class T> - void add_fcn (void (*action) (const T&), T val) - { - add (new fcn_crefarg_elem<T> (action, val)); - } - - // Call to T::method (void). - template <class T> - void add_method (T *obj, void (T::*method) (void)) - { - add (new method_elem<T> (obj, method)); - } - - // Call to delete (T*). - - template <class T> - void add_delete (T *obj) - { - add (new delete_ptr_elem<T> (obj)); - } + void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); } - // Protect any variable. - template <class T> - void protect_var (T& var) - { - add (new restore_var_elem<T> (var, var)); - } - - // Protect any variable, value given. - template <class T> - void protect_var (T& var, const T& val) - { - add (new restore_var_elem<T> (var, val)); - } - - operator bool (void) const - { - return head != 0; - } - - void run_top (void) - { - if (head) - { - // No leak on exception! - std::auto_ptr<elem> ptr (head); - head = ptr->next; - ptr->run (); - } - } - - void run_top (int num) - { - while (num-- > 0) - run_top (); - } + void discard_first (void) + { + if (! empty ()) + { + elem *ptr = lifo.top (); + lifo.pop (); + delete ptr; + } + } - void discard_top (void) - { - if (head) - { - elem *ptr = head; - head = ptr->next; - delete ptr; - } - } + void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); } - void discard_top (int num) - { - while (num-- > 0) - discard_top (); - } + size_t size (void) const { return lifo.size (); } - void run (void) - { - while (head) - run_top (); - } +protected: - void discard (void) - { - while (head) - discard_top (); - } - - // Destructor should not raise an exception, so all actions registered should - // be exception-safe (but setting error_state is allowed). If you're not sure, - // see unwind_protect_safe. - ~unwind_protect (void) - { - run (); - } + std::stack<elem *> lifo; private: - elem *head; - // No copying! unwind_protect (const unwind_protect&); @@ -314,24 +99,30 @@ unwind_protect& operator = (const unwind_protect&); }; -// Like unwind_protect, but this one will guard against the possibility of seeing -// an exception (or interrupt) in the cleanup actions. Not that we can do much about -// it, but at least we won't crash. +// Like unwind_protect, but this one will guard against the +// possibility of seeing an exception (or interrupt) in the cleanup +// actions. Not that we can do much about it, but at least we won't +// crash. class OCTINTERP_API unwind_protect_safe : public unwind_protect { +private: + static void gripe_exception (void); public: + + unwind_protect_safe (void) : unwind_protect () { } + ~unwind_protect_safe (void) { - while (*this) + while (! empty ()) { try { - run_top (); + run_first (); } catch (...) // Yes, the black hole. Remember we're in a dtor. { @@ -339,6 +130,14 @@ } } } + +private: + + // No copying! + + unwind_protect_safe (const unwind_protect_safe&); + + unwind_protect_safe& operator = (const unwind_protect_safe&); }; #endif
--- a/libinterp/interp-core/zfstream.cc +++ b/libinterp/interp-core/zfstream.cc @@ -473,6 +473,11 @@ if ((io_mode & std::ios_base::in) && way == std::ios_base::cur) computed_off += this->gptr () - this->egptr (); + // Handle tellg/tellp as a special case up front, no need to seek + // or invalidate get/put buffers + if (off == 0 && way == std::ios_base::cur) + return pos_type (gztell (file) + computed_off); + if (way == std::ios_base::beg) ret = pos_type (gzseek (file, computed_off, SEEK_SET)); else if (way == std::ios_base::cur)
--- a/libinterp/interpfcn/data.cc +++ b/libinterp/interpfcn/data.cc @@ -38,10 +38,10 @@ #include <ctime> #include <string> -#include <base64.h> #include "lo-ieee.h" #include "lo-math.h" +#include "oct-base64.h" #include "oct-time.h" #include "str-vec.h" #include "quit.h" @@ -1338,6 +1338,11 @@ %!assert (diag (int8 ([0, 1, 0, 0; 0, 0, 2, 0; 0, 0, 0, 3; 0, 0, 0, 0]), 1), int8 ([1; 2; 3])) %!assert (diag (int8 ([0, 0, 0, 0; 1, 0, 0, 0; 0, 2, 0, 0; 0, 0, 3, 0]), -1), int8 ([1; 2; 3])) +## bug #37411 +%!assert (diag (diag ([5, 2, 3])(:,1)), diag([5 0 0 ])) +%!assert (diag (diag ([5, 2, 3])(:,1), 2), [0 0 5 0 0; zeros(4, 5)]) +%!assert (diag (diag ([5, 2, 3])(:,1), -2), [[0 0 5 0 0]', zeros(5, 4)]) + ## Test non-square size %!assert (diag ([1,2,3], 6, 3), [1 0 0; 0 2 0; 0 0 3; 0 0 0; 0 0 0; 0 0 0]) %!assert (diag (1, 2, 3), [1,0,0; 0,0,0]); @@ -4111,53 +4116,53 @@ { if (args(0).is_single_type ()) { - float val = args(0).float_value (); + Array<float> x = args(0).float_array_value (); if (! error_state) - { - val = ::fabsf (val); - if (xisnan (val) || xisinf (val)) - retval = fill_matrix (octave_value ("single"), - lo_ieee_nan_value (), - lo_ieee_float_nan_value (), "eps"); - else if (val < std::numeric_limits<float>::min ()) - retval = fill_matrix (octave_value ("single"), 0e0, - powf (2.0, -149e0), "eps"); - else + { + Array<float> epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexpf (val, &expon); - val = std::pow (static_cast <float> (2.0), - static_cast <float> (expon - 24)); - retval = fill_matrix (octave_value ("single"), - std::numeric_limits<double>::epsilon (), - val, "eps"); + float val = ::fabsf (x(i)); + if (xisnan (val) || xisinf (val)) + epsval(i) = lo_ieee_nan_value (); + else if (val < std::numeric_limits<float>::min ()) + epsval(i) = powf (2.0, -149e0); + else + { + int expon; + frexpf (val, &expon); + epsval(i) = std::pow (static_cast <float> (2.0), + static_cast <float> (expon - 24)); + } } + retval = epsval; } } else { - double val = args(0).double_value (); + Array<double> x = args(0).array_value (); if (! error_state) { - val = ::fabs (val); - if (xisnan (val) || xisinf (val)) - retval = fill_matrix (octave_value_list (), - lo_ieee_nan_value (), - lo_ieee_float_nan_value (), "eps"); - else if (val < std::numeric_limits<double>::min ()) - retval = fill_matrix (octave_value_list (), - pow (2.0, -1074e0), 0e0, "eps"); - else + Array<double> epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexp (val, &expon); - val = std::pow (static_cast <double> (2.0), - static_cast <double> (expon - 53)); - retval = fill_matrix (octave_value_list (), val, - std::numeric_limits<float>::epsilon (), - "eps"); + double val = ::fabs (x(i)); + if (xisnan (val) || xisinf (val)) + epsval(i) = lo_ieee_nan_value (); + else if (val < std::numeric_limits<double>::min ()) + epsval(i) = pow (2.0, -1074e0); + else + { + int expon; + frexp (val, &expon); + epsval(i) = std::pow (static_cast <double> (2.0), + static_cast <double> (expon - 53)); + } + retval = epsval; } } } @@ -4179,6 +4184,8 @@ %!assert (eps (realmin/16), 2^(-1074)) %!assert (eps (Inf), NaN) %!assert (eps (NaN), NaN) +%!assert (eps ([1/2 1 2 realmax 0 realmin/2 realmin/16 Inf NaN]), +%! [2^(-53) 2^(-52) 2^(-51) 2^971 2^(-1074) 2^(-1074) 2^(-1074) NaN NaN]) %!assert (eps (single (1/2)), single (2^(-24))) %!assert (eps (single (1)), single (2^(-23))) %!assert (eps (single (2)), single (2^(-22))) @@ -4188,6 +4195,9 @@ %!assert (eps (realmin ("single")/16), single (2^(-149))) %!assert (eps (single (Inf)), single (NaN)) %!assert (eps (single (NaN)), single (NaN)) +%!assert (eps (single ([1/2 1 2 realmax("single") 0 realmin("single")/2 realmin("single")/16 Inf NaN])), +%! single ([2^(-24) 2^(-23) 2^(-22) 2^104 2^(-149) 2^(-149) 2^(-149) NaN NaN])) + */ DEFUN (pi, args, , @@ -6204,7 +6214,7 @@ */ // Sort the rows of the matrix @var{a} according to the order -// specified by @var{mode}, which can either be `ascend' or `descend' +// specified by @var{mode}, which can either be 'ascend' or 'descend' // and return the index vector corresponding to the sort order. // // This function does not yet support sparse matrices. @@ -7235,22 +7245,8 @@ return retval; } -bool do_base64_encode (const char * inc, const size_t inlen, char *& out) -{ - bool ret = false; - size_t outlen = base64_encode_alloc (inc, inlen, &out); - - if (! out && outlen == 0 && inlen != 0) - error ("base64_encode: input array too large"); - else if (! out) - error ("base64_encode: memory allocation error"); - else - ret = true; - - return ret; -} - -DEFUN (base64_encode, args, , "-*- texinfo -*-\n\ +DEFUN (base64_encode, args, , + "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{s} =} base64_encode (@var{x})\n\ Encode a double matrix or array @var{x} into the base64 format string\n\ @var{s}.\n\ @@ -7282,7 +7278,7 @@ reinterpret_cast<const char*> (in.data ()); \ char* out; \ if (! error_state \ - && do_base64_encode (inc, inlen, out)) \ + && octave_base64_encode (inc, inlen, &out)) \ retval(0) = octave_value (out); \ } @@ -7308,7 +7304,7 @@ inc = reinterpret_cast<const char*> (in.data ()); char* out; if (! error_state - && do_base64_encode (inc, inlen, out)) + && octave_base64_encode (inc, inlen, &out)) retval(0) = octave_value (out); } else @@ -7320,7 +7316,7 @@ inc = reinterpret_cast<const char*> (in.data ()); char* out; if (! error_state - && do_base64_encode (inc, inlen, out)) + && octave_base64_encode (inc, inlen, &out)) retval(0) = octave_value (out); } } @@ -7342,16 +7338,17 @@ %!error base64_encode (struct ()) */ -DEFUN (base64_decode, args, , "-*- texinfo -*-\n\ +DEFUN (base64_decode, args, , + "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{x} =} base64_decode (@var{s})\n\ @deftypefnx {Built-in Function} {@var{x} =} base64_decode (@var{s}, @var{dims})\n\ -Decode the double matrix or array @var{x} from the base64 format string\n\ +Decode the double matrix or array @var{x} from the base64 encoded string\n\ @var{s}. The optional input parameter @var{dims} should be a vector\n\ containing the dimensions of the decoded array.\n\ @seealso{base64_encode}\n\ @end deftypefn") { - octave_value_list retval; + octave_value retval; int nargin = args.length (); @@ -7359,54 +7356,32 @@ print_usage (); else { - dim_vector new_dims; - Array<double> res; + dim_vector dims; if (nargin > 1) { - const Array<octave_idx_type> new_size = + const Array<octave_idx_type> size = args(1).octave_idx_type_vector_value (); + if (! error_state) { - new_dims = dim_vector::alloc (new_size.length ()); - for (octave_idx_type i = 0; i < new_size.length (); i++) - new_dims(i) = new_size(i); + dims = dim_vector::alloc (size.length ()); + for (octave_idx_type i = 0; i < size.length (); i++) + dims(i) = size(i); } } - const std::string in = args(0).string_value (); + const std::string str = args(0).string_value (); if (! error_state) { - const char *inc = &(in[0]); - char *out; - size_t inlen = in.length (), outlen; - - bool ok = base64_decode_alloc (inc, inlen, &out, &outlen); - - if (! ok) - error ("base64_decode: input was not valid base64"); - else if (! out) - error ("base64_decode: memory allocation error"); - else - { - if ((outlen % (sizeof (double) / sizeof (char))) != 0) - error ("base64_decode: incorrect input size"); - else - { - octave_idx_type l; - l = (outlen * sizeof (char)) / sizeof (double); - res.resize1 (l); - double *dout = reinterpret_cast<double*> (out); - std::copy (dout, dout + l, res.fortran_vec ()); - - if (nargin > 1) - retval(0) = octave_value (res).reshape (new_dims); - else - retval(0) = octave_value (res); - } - } - } + Array<double> res = octave_base64_decode (str); + + if (nargin > 1) + res = res.reshape (dims); + + retval = res; + } } return retval;
--- a/libinterp/interpfcn/debug.cc +++ b/libinterp/interpfcn/debug.cc @@ -784,7 +784,7 @@ } } else - os << "dbtype: unable to open `" << ff << "' for reading!\n"; + os << "dbtype: unable to open '" << ff << "' for reading!\n"; } else os << "dbtype: unknown function " << name << "\n";
--- a/libinterp/interpfcn/debug.h +++ b/libinterp/interpfcn/debug.h @@ -129,6 +129,6 @@ bool do_have_breakpoints (void) { return (! bp_set.empty ()); } }; -std::string get_file_line (const std::string& fname, size_t line); +extern std::string get_file_line (const std::string& fname, size_t line); #endif
--- a/libinterp/interpfcn/defaults.cc +++ b/libinterp/interpfcn/defaults.cc @@ -93,6 +93,8 @@ std::string Vlocal_site_defaults_file; std::string Vsite_defaults_file; +std::string Vbuilt_in_docstrings_file; + std::string subst_octave_home (const std::string& s) { @@ -294,42 +296,54 @@ static void set_default_doc_cache_file (void) { - std::string def_file = subst_octave_home (OCTAVE_DOC_CACHE_FILE); + if (Vdoc_cache_file.empty ()) + { + std::string def_file = subst_octave_home (OCTAVE_DOC_CACHE_FILE); - std::string env_file = octave_env::getenv ("OCTAVE_DOC_CACHE_FILE"); + std::string env_file = octave_env::getenv ("OCTAVE_DOC_CACHE_FILE"); - Vdoc_cache_file = env_file.empty () ? def_file : env_file; + Vdoc_cache_file = env_file.empty () ? def_file : env_file; + } } static void set_default_texi_macros_file (void) { - std::string def_file = subst_octave_home (OCTAVE_TEXI_MACROS_FILE); + if (Vtexi_macros_file.empty ()) + { + std::string def_file = subst_octave_home (OCTAVE_TEXI_MACROS_FILE); - std::string env_file = octave_env::getenv ("OCTAVE_TEXI_MACROS_FILE"); + std::string env_file = octave_env::getenv ("OCTAVE_TEXI_MACROS_FILE"); - Vtexi_macros_file = env_file.empty () ? def_file : env_file; + Vtexi_macros_file = env_file.empty () ? def_file : env_file; + } } static void set_default_info_file (void) { - std::string std_info_file = subst_octave_home (OCTAVE_INFOFILE); + if (Vinfo_file.empty ()) + { + std::string std_info_file = subst_octave_home (OCTAVE_INFOFILE); - std::string oct_info_file = octave_env::getenv ("OCTAVE_INFO_FILE"); + std::string oct_info_file = octave_env::getenv ("OCTAVE_INFO_FILE"); - Vinfo_file = oct_info_file.empty () ? std_info_file : oct_info_file; + Vinfo_file = oct_info_file.empty () ? std_info_file : oct_info_file; + } } static void set_default_info_prog (void) { - std::string oct_info_prog = octave_env::getenv ("OCTAVE_INFO_PROGRAM"); + if (Vinfo_program.empty ()) + { + std::string oct_info_prog = octave_env::getenv ("OCTAVE_INFO_PROGRAM"); - if (oct_info_prog.empty ()) - Vinfo_program = "info"; - else - Vinfo_program = std::string (oct_info_prog); + if (oct_info_prog.empty ()) + Vinfo_program = "info"; + else + Vinfo_program = std::string (oct_info_prog); + } } static void @@ -371,6 +385,21 @@ Vsite_defaults_file = sf; } +static void +set_built_in_docstrings_file (void) +{ + if (Vbuilt_in_docstrings_file.empty ()) + { + std::string df = octave_env::getenv ("OCTAVE_BUILT_IN_DOCSTRINGS_FILE"); + + if (df.empty ()) + Vbuilt_in_docstrings_file + = Voct_etc_dir + file_ops::dir_sep_str () + "built-in-docstrings"; + else + Vbuilt_in_docstrings_file = df; + } +} + void install_defaults (void) { @@ -424,6 +453,8 @@ set_local_site_defaults_file (); set_site_defaults_file (); + + set_built_in_docstrings_file (); } DEFUN (EDITOR, args, nargout,
--- a/libinterp/interpfcn/defaults.in.h +++ b/libinterp/interpfcn/defaults.in.h @@ -176,45 +176,47 @@ #define OCTAVE_RELEASE %OCTAVE_RELEASE% #endif -extern std::string Voctave_home; +extern OCTINTERP_API std::string Voctave_home; -extern std::string Vbin_dir; -extern std::string Vinfo_dir; -extern std::string Vdata_dir; -extern std::string Vlibexec_dir; -extern std::string Varch_lib_dir; -extern std::string Vlocal_arch_lib_dir; -extern std::string Vlocal_ver_arch_lib_dir; +extern OCTINTERP_API std::string Vbin_dir; +extern OCTINTERP_API std::string Vinfo_dir; +extern OCTINTERP_API std::string Vdata_dir; +extern OCTINTERP_API std::string Vlibexec_dir; +extern OCTINTERP_API std::string Varch_lib_dir; +extern OCTINTERP_API std::string Vlocal_arch_lib_dir; +extern OCTINTERP_API std::string Vlocal_ver_arch_lib_dir; -extern std::string Vlocal_ver_oct_file_dir; -extern std::string Vlocal_api_oct_file_dir; -extern std::string Vlocal_oct_file_dir; +extern OCTINTERP_API std::string Vlocal_ver_oct_file_dir; +extern OCTINTERP_API std::string Vlocal_api_oct_file_dir; +extern OCTINTERP_API std::string Vlocal_oct_file_dir; -extern std::string Vlocal_ver_fcn_file_dir; -extern std::string Vlocal_api_fcn_file_dir; -extern std::string Vlocal_fcn_file_dir; +extern OCTINTERP_API std::string Vlocal_ver_fcn_file_dir; +extern OCTINTERP_API std::string Vlocal_api_fcn_file_dir; +extern OCTINTERP_API std::string Vlocal_fcn_file_dir; -extern std::string Voct_etc_dir; +extern OCTINTERP_API std::string Voct_etc_dir; -extern std::string Voct_file_dir; -extern std::string Vfcn_file_dir; +extern OCTINTERP_API std::string Voct_file_dir; +extern OCTINTERP_API std::string Vfcn_file_dir; -extern std::string Vimage_dir; +extern OCTINTERP_API std::string Vimage_dir; // Name of the editor to be invoked by the edit_history command. -extern std::string VEDITOR; +extern OCTINTERP_API std::string VEDITOR; -extern std::string Vlocal_site_defaults_file; -extern std::string Vsite_defaults_file; +extern OCTINTERP_API std::string Vlocal_site_defaults_file; +extern OCTINTERP_API std::string Vsite_defaults_file; + +extern OCTINTERP_API std::string Vbuilt_in_docstrings_file; // Name of the FFTW wisdom program. extern OCTINTERP_API std::string Vfftw_wisdom_program; -extern std::string subst_octave_home (const std::string&); +extern OCTINTERP_API std::string subst_octave_home (const std::string&); -extern void install_defaults (void); +extern OCTINTERP_API void install_defaults (void); -extern void set_exec_path (const std::string& path = std::string ()); -extern void set_image_path (const std::string& path = std::string ()); +extern OCTINTERP_API void set_exec_path (const std::string& path = std::string ()); +extern OCTINTERP_API void set_image_path (const std::string& path = std::string ()); #endif
--- a/libinterp/interpfcn/defun.cc +++ b/libinterp/interpfcn/defun.cc @@ -68,7 +68,7 @@ { if (version != OCTAVE_API_VERSION) { - error ("API version %s found in .oct file function `%s'\n" + error ("API version %s found in .oct file function '%s'\n" " does not match the running Octave (API version %s)\n" " this can lead to incorrect results or other failures\n" " you can fix this problem by recompiling this .oct file",
--- a/libinterp/interpfcn/defun.h +++ b/libinterp/interpfcn/defun.h @@ -44,7 +44,7 @@ #define DEFUN(name, args_name, nargout_name, doc) \ DEFUN_INTERNAL (name, args_name, nargout_name, doc) -// This one can be used when `name' cannot be used directly (if it is +// This one can be used when 'name' cannot be used directly (if it is // already defined as a macro). In that case, name is already a // quoted string, and the internal name of the function must be passed // too (the convention is to use a prefix of "F", so "foo" becomes "Ffoo").
--- a/libinterp/interpfcn/error.cc +++ b/libinterp/interpfcn/error.cc @@ -110,7 +110,7 @@ // Tell the error handler whether to print messages, or just store // them for later. Used for handling errors in eval() and -// the `unwind_protect' statement. +// the 'unwind_protect' statement. int buffer_error_messages = 0; // TRUE means error messages are turned off. @@ -921,10 +921,10 @@ if (l > 0) { if (c > 0) - pr_where_1 ("error: called from `%s' near line %d, column %d", + pr_where_1 ("error: called from '%s' near line %d, column %d", nm.c_str (), l, c); else - pr_where_1 ("error: called from `%d' near line %d", nm.c_str (), l); + pr_where_1 ("error: called from '%d' near line %d", nm.c_str (), l); } } } @@ -946,10 +946,10 @@ if (l > 0) { if (c > 0) - pr_where_1 ("error: called from `%s' in file %s near line %d, column %d", + pr_where_1 ("error: called from '%s' in file %s near line %d, column %d", nm.c_str (), file.c_str (), l, c); else - pr_where_1 ("error: called from `%d' in file %s near line %d", nm.c_str (), file.c_str (), l); + pr_where_1 ("error: called from '%d' in file %s near line %d", nm.c_str (), file.c_str (), l); } } } @@ -1141,6 +1141,59 @@ return retval; } +static octave_scalar_map +warning_query (const std::string& id_arg) +{ + octave_scalar_map retval; + + std::string id = id_arg; + + if (id == "last") + id = Vlast_warning_id; + + Cell ident = warning_options.contents ("identifier"); + Cell state = warning_options.contents ("state"); + + octave_idx_type nel = ident.numel (); + + bool found = false; + + std::string val; + + for (octave_idx_type i = 0; i < nel; i++) + { + if (ident(i).string_value () == id) + { + val = state(i).string_value (); + found = true; + break; + } + } + + if (! found) + { + for (octave_idx_type i = 0; i < nel; i++) + { + if (ident(i).string_value () == "all") + { + val = state(i).string_value (); + found = true; + break; + } + } + } + + if (found) + { + retval.assign ("identifier", id); + retval.assign ("state", val); + } + else + error ("warning: unable to find default warning state!"); + + return retval; +} + DEFUN (warning, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} warning (@var{template}, @dots{})\n\ @@ -1149,6 +1202,7 @@ @deftypefnx {Built-in Function} {} warning (\"off\", @var{id})\n\ @deftypefnx {Built-in Function} {} warning (\"query\", @var{id})\n\ @deftypefnx {Built-in Function} {} warning (\"error\", @var{id})\n\ +@deftypefnx {Built-in Function} {} warning (@var{state}, @var{id}, \"local\")\n\ Format the optional arguments under the control of the template string\n\ @var{template} using the same rules as the @code{printf} family of\n\ functions (@pxref{Formatted Output}) and print the resulting message\n\ @@ -1159,8 +1213,10 @@ to go on.\n\ \n\ The optional message identifier allows users to enable or disable\n\ -warnings tagged by @var{id}. The special identifier @samp{\"all\"} may\n\ -be used to set the state of all warnings.\n\ +warnings tagged by @var{id}. A message identifier is of the form\n\ +\"NAMESPACE:WARNING-NAME\". Octave's own warnings use the \"Octave\"\n\ +namespace (@pxref{doc-warning_ids}). The special identifier @samp{\"all\"}\n\ +may be used to set the state of all warnings.\n\ \n\ If the first argument is @samp{\"on\"} or @samp{\"off\"}, set the state\n\ of a particular warning using the identifier @var{id}. If the first\n\ @@ -1176,6 +1232,15 @@ @end group\n\ @end example\n\ \n\ +If the state is @samp{\"on\"}, @samp{\"off\"}, or @samp{\"error\"}\n\ +and the third argument is @samp{\"local\"}, then the warning state\n\ +will be set temporarily, until the end of the current function.\n\ +Changes to warning states that are set locally affect the current\n\ +function and all functions called from the current scope. The\n\ +previous warning state is restored on return from the current\n\ +function. The \"local\" option is ignored if used in the top-level\n\ +workspace.\n\ +\n\ Implementation Note: For compatibility with @sc{matlab}, escape\n\ sequences (e.g., \"\\n\" => newline) are processed in @var{template}\n\ regardless of whether @var{template} has been defined within single quotes\n\ @@ -1201,13 +1266,93 @@ std::string arg1 = argv(1); std::string arg2 = "all"; - if (argc == 3) + if (argc >= 3) arg2 = argv(2); if (arg1 == "on" || arg1 == "off" || arg1 == "error") { octave_map old_warning_options = warning_options; + if (argc == 4 && argv(3) == "local" + && ! symbol_table::at_top_level ()) + { + symbol_table::scope_id scope + = octave_call_stack::current_scope (); + + symbol_table::context_id context + = octave_call_stack::current_context (); + + octave_scalar_map val = warning_query (arg2); + + octave_value curr_state = val.contents ("state"); + + // FIXME -- this might be better with a dictionary + // object. + + octave_value curr_warning_states + = symbol_table::varval (".saved_warning_states.", + scope, context); + + octave_map m; + + if (curr_warning_states.is_defined ()) + m = curr_warning_states.map_value (); + else + { + string_vector fields (2); + + fields(0) = "identifier"; + fields(1) = "state"; + + m = octave_map (dim_vector (0, 1), fields); + } + + if (error_state) + panic_impossible (); + + Cell ids = m.contents ("identifier"); + Cell states = m.contents ("state"); + + octave_idx_type nel = states.numel (); + bool found = false; + octave_idx_type i; + for (i = 0; i < nel; i++) + { + std::string id = ids(i).string_value (); + + if (error_state) + panic_impossible (); + + if (id == arg2) + { + states(i) = curr_state; + found = true; + break; + } + } + + if (! found) + { + m.resize (dim_vector (nel+1, 1)); + + ids.resize (dim_vector (nel+1, 1)); + states.resize (dim_vector (nel+1, 1)); + + ids(nel) = arg2; + states(nel) = curr_state; + } + + m.contents ("identifier") = ids; + m.contents ("state") = states; + + symbol_table::varref + (".saved_warning_states.", scope, context) = m; + + // Now ignore the "local" argument and continue to + // handle the current setting. + argc--; + } + if (arg2 == "all") { octave_map tmp; @@ -1369,54 +1514,7 @@ retval = tmp; } else - { - if (arg2 == "last") - arg2 = Vlast_warning_id; - - Cell ident = warning_options.contents ("identifier"); - Cell state = warning_options.contents ("state"); - - octave_idx_type nel = ident.numel (); - - bool found = false; - - std::string val; - - for (octave_idx_type i = 0; i < nel; i++) - { - if (ident(i).string_value () == arg2) - { - val = state(i).string_value (); - found = true; - break; - } - } - - if (! found) - { - for (octave_idx_type i = 0; i < nel; i++) - { - if (ident(i).string_value () == "all") - { - val = state(i).string_value (); - found = true; - break; - } - } - } - - if (found) - { - octave_scalar_map tmp; - - tmp.assign ("identifier", arg2); - tmp.assign ("state", val); - - retval = tmp; - } - else - error ("warning: unable to find default warning state!"); - } + retval = warning_query (arg2); done = true; } @@ -1441,7 +1539,7 @@ if (m.contains ("identifier") && m.contains ("state")) warning_options = m; else - error ("warning: expecting structure with fields `identifier' and `state'"); + error ("warning: expecting structure with fields 'identifier' and 'state'"); done = true;
--- a/libinterp/interpfcn/error.h +++ b/libinterp/interpfcn/error.h @@ -30,7 +30,7 @@ class unwind_protect; #define panic_impossible() \ - panic ("impossible state reached in file `%s' at line %d", \ + panic ("impossible state reached in file '%s' at line %d", \ __FILE__, __LINE__) extern OCTINTERP_API void reset_error_handler (void); @@ -122,7 +122,7 @@ // Tell the error handler whether to print messages, or just store // them for later. Used for handling errors in eval() and -// the `unwind_protect' statement. +// the 'unwind_protect' statement. extern OCTINTERP_API int buffer_error_messages; // TRUE means error messages are turned off.
--- a/libinterp/interpfcn/file-io.cc +++ b/libinterp/interpfcn/file-io.cc @@ -1164,7 +1164,7 @@ catch (std::runtime_error) { // Display a warning if the specified locale is unknown - warning ("fscanf: invalid locale. Try `locale -a' for a list of supported values."); + warning ("fscanf: invalid locale. Try 'locale -a' for a list of supported values."); oldloc = std::locale::classic (); } retval = os.oscanf (args(1), who); @@ -1274,7 +1274,7 @@ catch (std::runtime_error) { // Display a warning if the specified locale is unknown - warning ("sscanf: invalid locale. Try `locale -a' for a list of supported values."); + warning ("sscanf: invalid locale. Try 'locale -a' for a list of supported values."); } retval = os.oscanf (args(1), who); } @@ -2049,8 +2049,7 @@ in binary mode and with the @w{@code{O_EXCL}} flag.\n\ \n\ If the optional argument @var{delete} is supplied and is true,\n\ -the file will be deleted automatically when Octave exits, or when\n\ -the function @code{purge_tmp_files} is called.\n\ +the file will be deleted automatically when Octave exits.\n\ \n\ If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\ the file, and @var{msg} is an empty string. Otherwise, @var{fid}\n\
--- a/libinterp/interpfcn/graphics.cc +++ b/libinterp/interpfcn/graphics.cc @@ -42,6 +42,7 @@ #include "oct-locbuf.h" #include "singleton-cleanup.h" +#include "builtins.h" #include "cutils.h" #include "defun.h" #include "display.h" @@ -1802,7 +1803,7 @@ pval_map[pname] = val; } else - error ("invalid %s property `%s'", pfx.c_str (), pname.c_str ()); + error ("invalid %s property '%s'", pfx.c_str (), pname.c_str ()); } } @@ -7780,7 +7781,7 @@ obj.initialize (); } else - error ("gh_manager::do_make_graphics_handle: invalid object type `%s'", + error ("gh_manager::do_make_graphics_handle: invalid object type '%s'", go_name.c_str ()); return h; @@ -8202,7 +8203,7 @@ if (Vdrawnow_requested && ! old_Vdrawnow_requested) { - feval ("drawnow"); + Fdrawnow (); Vdrawnow_requested = false; } @@ -9350,7 +9351,7 @@ retval = pl->second; } else - error ("default graphics toolkit `%s' is not available!", + error ("default graphics toolkit '%s' is not available!", dtk.c_str ()); } else @@ -9474,7 +9475,7 @@ do_events = false; else { - error ("drawnow: invalid argument, expected `expose' as argument"); + error ("drawnow: invalid argument, expected 'expose' as argument"); return retval; } } @@ -9516,7 +9517,7 @@ if (! (fs && fs.is_dir ())) { - error ("drawnow: nonexistent directory `%s'", + error ("drawnow: nonexistent directory '%s'", dirname.c_str ()); return retval; @@ -9828,7 +9829,7 @@ go.get_properties ().insert_property (name, p); } else - error ("addproperty: a `%s' property already exists in the graphics object", + error ("addproperty: a '%s' property already exists in the graphics object", name.c_str ()); } else @@ -10190,10 +10191,10 @@ if (s.compare ("timeout")) timeout_index = max_arg_index + 1; else - error ("waitfor: invalid parameter `%s'", s.c_str ()); + error ("waitfor: invalid parameter '%s'", s.c_str ()); } else - error ("waitfor: invalid parameter, expected `timeout'"); + error ("waitfor: invalid parameter, expected 'timeout'"); } if (! error_state && timeout_index >= 0)
--- a/libinterp/interpfcn/graphics.in.h +++ b/libinterp/interpfcn/graphics.in.h @@ -3250,7 +3250,7 @@ retval = factory_properties.lookup (name); if (retval.is_undefined ()) - error ("get: invalid default property `%s'", name.c_str ()); + error ("get: invalid default property '%s'", name.c_str ()); } return retval; @@ -3261,7 +3261,7 @@ octave_value retval = factory_properties.lookup (name); if (retval.is_undefined ()) - error ("get: invalid factory default property `%s'", name.c_str ()); + error ("get: invalid factory default property '%s'", name.c_str ()); return retval; } @@ -4810,6 +4810,8 @@ // properties declarations. BEGIN_PROPERTIES (hggroup) + string_property displayname , "" + radio_property erasemode , "{normal}|none|xor|background" // hidden properties for limit computation row_vector_property xlim hr , Matrix () row_vector_property ylim hr , Matrix ()
--- a/libinterp/interpfcn/help.cc +++ b/libinterp/interpfcn/help.cc @@ -922,6 +922,95 @@ return h; } + +DEFUN (built_in_docstrings_file, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} built_in_docstrings_file ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} built_in_docstrings_file (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} built_in_docstrings_file (@var{new_val}, \"local\")\n\ +Query or set the internal variable that specifies the name of the\n\ +file containing docstrings for built-in Octave functions.\n\ +\n\ +Note that this variable is only used when Octave is initializing itself,\n\ +so setting it will have no effect.\n\ +@end deftypefn") +{ + return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (built_in_docstrings_file); +} + +void +install_built_in_docstrings (void) +{ + std::string fname = Vbuilt_in_docstrings_file; + + std::ifstream file (fname.c_str (), std::ios::in | std::ios::binary); + + if (file) + { + // Ignore header; + file.ignore (1000, 0x1f); + + if (file.gcount () == 1000) + { + // We use std::cerr here instead of calling Octave's warning + // function because install_built_in_docstrings is called + // before the interpreter is initialized, so warning messages + // won't work properly. + + std::cerr << "warning: is builtin-docstrings file corrupted?" + << std::endl; + return; + } + + // FIXME -- eliminate fixed buffer size. + size_t bufsize = 100000; + + OCTAVE_LOCAL_BUFFER (char, buf, bufsize); + + while (! file.eof ()) + { + file.getline (buf, bufsize, 0x1f); + + std::string tmp (buf); + + size_t pos = tmp.find ('\n'); + + std::string fcn = tmp.substr (0, pos); + + octave_value ov = symbol_table::find_built_in_function (fcn); + + if (ov.is_defined ()) + { + octave_function *fp = ov.function_value (); + + if (fp) + { + tmp = tmp.substr (pos+1); + + // Strip @c FILENAME which is part of current DOCSTRINGS + // syntax. This may disappear if a specific format for + // docstring files is developed. + while (tmp.length () > 2 && tmp[0] == '@' && tmp[1] == 'c') + { + pos = tmp.find ('\n'); + tmp = tmp.substr (pos+1); + } + + fp->document (tmp); + } + } + } + } + else + { + // See note above about using std::cerr instead of warning. + + std::cerr << "warning: docstring file '" << fname << "' not found" + << std::endl; + } + +} + static void do_get_help_text (const std::string& name, std::string& text, std::string& format)
--- a/libinterp/interpfcn/help.h +++ b/libinterp/interpfcn/help.h @@ -32,6 +32,8 @@ extern OCTINTERP_API std::string raw_help (const std::string&, bool&); +extern OCTINTERP_API void install_built_in_docstrings (void); + // Name of the doc cache file specified on the command line. // (--doc-cache-file file) extern std::string Vdoc_cache_file;
--- a/libinterp/interpfcn/input.cc +++ b/libinterp/interpfcn/input.cc @@ -422,7 +422,7 @@ return status; } -// Fix things up so that input can come from file `name', printing a +// Fix things up so that input can come from file 'name', printing a // warning if the file doesn't exist. FILE * @@ -765,7 +765,7 @@ // Unmark forced variables. // Restore previous value of global_command. - frame.run_top (2); + frame.run (2); octave_quit (); }
--- a/libinterp/interpfcn/load-path.cc +++ b/libinterp/interpfcn/load-path.cc @@ -603,7 +603,7 @@ do_append (*i, warn); // Restore add hook and execute for all newly added directories. - frame.run_top (); + frame.run_first (); for (dir_info_list_iterator i = dir_info_list.begin (); i != dir_info_list.end (); @@ -656,7 +656,7 @@ if (len > 1 && dir_arg.substr (len-2) == "//") warning_with_id ("Octave:recursive-path-search", - "trailing `//' is no longer special in search path elements"); + "trailing '//' is no longer special in search path elements"); std::string dir = file_ops::tilde_expand (dir_arg);
--- a/libinterp/interpfcn/load-save.cc +++ b/libinterp/interpfcn/load-save.cc @@ -121,7 +121,7 @@ } // The format string for the comment line at the top of text-format -// save files. Passed to strftime. Should begin with `#' and contain +// save files. Passed to strftime. Should begin with '#' and contain // no newline characters. static std::string Vsave_header_format_string = default_save_header_format (); @@ -129,11 +129,11 @@ gripe_file_open (const std::string& fcn, const std::string& file) { if (fcn == "load") - error ("%s: unable to open input file `%s'", fcn.c_str (), file.c_str ()); + error ("%s: unable to open input file '%s'", fcn.c_str (), file.c_str ()); else if (fcn == "save") - error ("%s: unable to open output file `%s'", fcn.c_str (), file.c_str ()); + error ("%s: unable to open output file '%s'", fcn.c_str (), file.c_str ()); else - error ("%s: unable to open file `%s'", fcn.c_str (), file.c_str ()); + error ("%s: unable to open file '%s'", fcn.c_str (), file.c_str ()); } // Install a variable with name NAME and the value VAL in the @@ -394,7 +394,7 @@ if (tc.is_defined ()) { if (format == LS_MAT_ASCII && argv_idx < argc) - warning ("load: loaded ASCII file `%s' -- ignoring extra args", + warning ("load: loaded ASCII file '%s' -- ignoring extra args", orig_fname.c_str ()); if (format == LS_MAT_ASCII @@ -442,12 +442,12 @@ break; } else - error ("load: unable to load variable `%s'", name.c_str ()); + error ("load: unable to load variable '%s'", name.c_str ()); } else { if (count == 0) - error ("load: are you sure `%s' is an Octave data file?", + error ("load: are you sure '%s' is an Octave data file?", orig_fname.c_str ()); break; @@ -873,7 +873,7 @@ file.close (); } else - error ("load: unable to open input file `%s'", + error ("load: unable to open input file '%s'", orig_fname.c_str ()); } } @@ -1121,6 +1121,14 @@ use_zlib = true; } #endif + else if (argv[i] == "-struct") + { + retval.append (argv[i]); + } + else if (argv[i][0] == '-') + { + error ("save: Unrecognized option '%s'", argv[i].c_str ()); + } else retval.append (argv[i]); } @@ -1269,7 +1277,7 @@ if (! symbol_table::is_variable (struct_name)) { - error ("save: no such variable: `%s'", struct_name.c_str ()); + error ("save: no such variable: '%s'", struct_name.c_str ()); return; } @@ -1277,7 +1285,7 @@ if (! struct_var.is_map () || struct_var.numel () != 1) { - error ("save: `%s' is not a scalar structure", + error ("save: '%s' is not a scalar structure", struct_name.c_str ()); return; } @@ -1292,7 +1300,7 @@ if (! save_fields (os, struct_var_map, argv[i], fmt, save_as_floats)) { - warning ("save: no such field `%s.%s'", + warning ("save: no such field '%s.%s'", struct_name.c_str (), argv[i].c_str ()); } } @@ -1305,7 +1313,7 @@ for (int i = argv_idx; i < argc; i++) { if (! save_vars (os, argv[i], fmt, save_as_floats)) - warning ("save: no such variable `%s'", argv[i].c_str ()); + warning ("save: no such variable '%s'", argv[i].c_str ()); } } } @@ -1350,7 +1358,7 @@ } } - message (0, "save to `%s' complete", fname); + message (0, "save to '%s' complete", fname); } void @@ -1362,7 +1370,7 @@ const char *fname = Voctave_core_file_name.c_str (); - message (0, "attempting to save variables to `%s'...", fname); + message (0, "attempting to save variables to '%s'...", fname); load_save_format format = LS_BINARY; @@ -1404,7 +1412,7 @@ file.close (); } else - warning ("unable to open `%s' for writing...", fname); + warning ("unable to open '%s' for writing...", fname); } else #endif /* HAVE_HDF5 */ @@ -1423,7 +1431,7 @@ file.close (); } else - warning ("unable to open `%s' for writing...", fname); + warning ("unable to open '%s' for writing...", fname); } else #endif @@ -1437,13 +1445,12 @@ file.close (); } else - warning ("unable to open `%s' for writing...", fname); + warning ("unable to open '%s' for writing...", fname); } } } } - DEFUN (save, args, , "-*- texinfo -*-\n\ @deftypefn {Command} {} save file\n\ @@ -1637,7 +1644,7 @@ } } - // Guard against things like `save a*', which are probably mistakes... + // Guard against things like 'save a*', which are probably mistakes... else if (i == argc - 1 && glob_pattern_p (argv[i])) {
--- a/libinterp/interpfcn/ls-oct-ascii.cc +++ b/libinterp/interpfcn/ls-oct-ascii.cc @@ -155,7 +155,7 @@ // // The input file must have a header followed by some data. // -// All lines in the header must begin with a `#' character. +// All lines in the header must begin with a '#' character. // // The header must contain a list of keyword and value pairs with the // keyword and value separated by a colon. @@ -244,7 +244,7 @@ if (name.empty ()) { if (count == 0) - error ("load: empty name keyword or no data found in file `%s'", + error ("load: empty name keyword or no data found in file '%s'", filename.c_str ()); return std::string (); @@ -253,7 +253,7 @@ if (! (name == ".nargin." || name == ".nargout." || name == CELL_ELT_TAG || valid_identifier (name))) { - error ("load: bogus identifier `%s' found in file `%s'", + error ("load: bogus identifier '%s' found in file '%s'", name.c_str (), filename.c_str ()); return std::string (); } @@ -283,7 +283,7 @@ tc = octave_value_typeinfo::lookup_type (typ); if (! tc.load_ascii (is)) - error ("load: trouble reading ascii file `%s'", filename.c_str ()); + error ("load: trouble reading ascii file '%s'", filename.c_str ()); } else error ("load: failed to extract keyword specifying value type");
--- a/libinterp/interpfcn/module.mk +++ b/libinterp/interpfcn/module.mk @@ -3,7 +3,7 @@ interpfcn/defaults.in.h \ interpfcn/graphics.in.h -INTERPFCN_INCLUDES = \ +INTERPFCN_INC = \ interpfcn/data.h \ interpfcn/debug.h \ interpfcn/defun.h \ @@ -65,13 +65,7 @@ $(AWK) -v emit_graphics_props=1 -f $(srcdir)/genprops.awk $< > $@-t mv $@-t $@ -## FIXME: Do these rules work correctly after transplant to interpfcn/ dir? -__fltk_uigetfile__.lo __fltk_uigetfile__.o: \ - AM_CXXFLAGS := $(filter-out $(DLL_CXXDEFS), $(AM_CXXFLAGS) $(GRAPHICS_CFLAGS)) - -__init_fltk__.lo __init_fltk__.o: \ - AM_CXXFLAGS := $(filter-out $(DLL_CXXDEFS), $(AM_CXXFLAGS) $(GRAPHICS_CFLAGS)) - noinst_LTLIBRARIES += interpfcn/libinterpfcn.la interpfcn_libinterpfcn_la_SOURCES = $(INTERPFCN_SRC) +interpfcn_libinterpfcn_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS)
--- a/libinterp/interpfcn/oct-hist.cc +++ b/libinterp/interpfcn/oct-hist.cc @@ -149,7 +149,7 @@ command_history::set_file (argv[i+1]); if (option == "-a") - // Append `new' lines to file. + // Append 'new' lines to file. command_history::append (); else if (option == "-w") @@ -161,7 +161,7 @@ command_history::read (); else if (option == "-n") - // Read `new' history from file. + // Read 'new' history from file. command_history::read_range (); else @@ -187,9 +187,9 @@ if (sscanf (argv[i].c_str (), "%d", &limit) != 1) { if (argv[i][0] == '-') - error ("history: unrecognized option `%s'", argv[i].c_str ()); + error ("history: unrecognized option '%s'", argv[i].c_str ()); else - error ("history: bad non-numeric arg `%s'", argv[i].c_str ()); + error ("history: bad non-numeric arg '%s'", argv[i].c_str ()); return; } @@ -260,10 +260,10 @@ return line; } -// Use `command' to replace the last entry in the history list, which, -// by this time, is `run_history blah...'. The intent is that the -// new command becomes the history entry, and that `fc' should never -// appear in the history list. This way you can do `run_history' to +// Use 'command' to replace the last entry in the history list, which, +// by this time, is 'run_history blah...'. The intent is that the +// new command becomes the history entry, and that 'fc' should never +// appear in the history list. This way you can do 'run_history' to // your heart's content. static void @@ -393,7 +393,7 @@ if (! file) { - error ("%s: couldn't open temporary file `%s'", warn_for, + error ("%s: couldn't open temporary file '%s'", warn_for, name.c_str ()); return retval; }
--- a/libinterp/interpfcn/pager.cc +++ b/libinterp/interpfcn/pager.cc @@ -509,7 +509,7 @@ external_diary_file.open (diary_file.c_str (), std::ios::app); if (! external_diary_file) - error ("diary: can't open diary file `%s'", diary_file.c_str ()); + error ("diary: can't open diary file '%s'", diary_file.c_str ()); } DEFUN (diary, args, , @@ -612,7 +612,7 @@ else if (arg == "off") Vpage_screen_output = false; else - error ("more: unrecognized argument `%s'", arg.c_str ()); + error ("more: unrecognized argument '%s'", arg.c_str ()); } else if (argc == 1) Vpage_screen_output = ! Vpage_screen_output;
--- a/libinterp/interpfcn/pr-output.cc +++ b/libinterp/interpfcn/pr-output.cc @@ -58,8 +58,8 @@ #include "utils.h" #include "variables.h" -// TRUE means use a scaled fixed point format for `format long' and -// `format short'. +// TRUE means use a scaled fixed point format for 'format long' and +// 'format short'. static bool Vfixed_point_format = false; // The maximum field width for a number printed by the default output @@ -3633,7 +3633,7 @@ } else { - error ("format: unrecognized option `short %s'", + error ("format: unrecognized option 'short %s'", arg.c_str ()); return; } @@ -3678,7 +3678,7 @@ } else { - error ("format: unrecognized option `long %s'", + error ("format: unrecognized option 'long %s'", arg.c_str ()); return; } @@ -3757,7 +3757,7 @@ Vcompact_format = false; } else - error ("format: unrecognized format state `%s'", arg.c_str ()); + error ("format: unrecognized format state '%s'", arg.c_str ()); } else {
--- a/libinterp/interpfcn/symtab.cc +++ b/libinterp/interpfcn/symtab.cc @@ -1492,8 +1492,11 @@ } } else if (nest_children.size ()) - for (table_iterator ti = table.begin (); ti != table.end (); ++ti) - ti->second.set_curr_fcn (curr_fcn); + { + static_workspace = true; + for (table_iterator ti = table.begin (); ti != table.end (); ++ti) + ti->second.set_curr_fcn (curr_fcn); + } for (std::vector<symbol_table*>::iterator iter = nest_children.begin (); iter != nest_children.end (); ++iter) @@ -1701,7 +1704,7 @@ retval = symbol_table::varval (name); if (retval.is_undefined ()) - error ("variable_value: `%s' is not a variable in the current scope", + error ("variable_value: '%s' is not a variable in the current scope", name.c_str ()); } else
--- a/libinterp/interpfcn/symtab.h +++ b/libinterp/interpfcn/symtab.h @@ -199,6 +199,10 @@ // temporary variables forced into symbol table for parsing static const unsigned int forced = 128; + // this symbol may NOT become a variable. + // (symbol added to a static workspace) + static const unsigned int added_static = 256; + private: class @@ -348,6 +352,7 @@ bool is_global (void) const { return storage_class & global; } bool is_persistent (void) const { return storage_class & persistent; } bool is_forced (void) const { return storage_class & forced; } + bool is_added_static (void) const {return storage_class & added_static; } void mark_local (void) { storage_class |= local; } void mark_automatic (void) { storage_class |= automatic; } @@ -369,6 +374,7 @@ storage_class |= persistent; } void mark_forced (void) { storage_class |= forced; } + void mark_added_static (void) { storage_class |= added_static; } void unmark_local (void) { storage_class &= ~local; } void unmark_automatic (void) { storage_class &= ~automatic; } @@ -378,6 +384,7 @@ void unmark_global (void) { storage_class &= ~global; } void unmark_persistent (void) { storage_class &= ~persistent; } void unmark_forced (void) { storage_class &= ~forced; } + void unmark_added_static (void) { storage_class &= ~added_static; } void init_persistent (void) { @@ -403,7 +410,7 @@ symbol_table::erase_persistent (name); } - context_id active_context (void) const; + OCTINTERP_API context_id active_context (void) const; scope_id scope (void) const { return decl_scope; } @@ -535,6 +542,7 @@ bool is_inherited (void) const { return rep->is_inherited (); } bool is_persistent (void) const { return rep->is_persistent (); } bool is_forced (void) const { return rep->is_forced (); } + bool is_added_static (void) const { return rep->is_added_static (); } void mark_local (void) { rep->mark_local (); } void mark_automatic (void) { rep->mark_automatic (); } @@ -544,6 +552,7 @@ void mark_global (void) { rep->mark_global (); } void mark_persistent (void) { rep->mark_persistent (); } void mark_forced (void) { rep->mark_forced (); } + void mark_added_static (void) { rep->mark_added_static (); } void unmark_local (void) { rep->unmark_local (); } void unmark_automatic (void) { rep->unmark_automatic (); } @@ -553,6 +562,7 @@ void unmark_global (void) { rep->unmark_global (); } void unmark_persistent (void) { rep->unmark_persistent (); } void unmark_forced (void) { rep->unmark_forced (); } + void unmark_added_static (void) { rep->unmark_added_static (); } void init_persistent (void) { rep->init_persistent (); } @@ -1207,13 +1217,23 @@ static octave_value& varref (const std::string& name, scope_id scope = xcurrent_scope, - context_id context = xdefault_context) + context_id context = xdefault_context, + bool force_add = false) { static octave_value foobar; symbol_table *inst = get_instance (scope); - return inst ? inst->do_varref (name, context) : foobar; + return inst ? inst->do_varref (name, context, force_add) : foobar; + } + + // Convenience function to greatly simplify + // octave_user_function::bind_automatic_vars + static octave_value& force_varref (const std::string& name, + scope_id scope = xcurrent_scope, + context_id context = xdefault_context) + { + return varref (name, scope, context, true); } static octave_value varval (const std::string& name, @@ -1573,7 +1593,7 @@ } // FIXME -- is this necessary, or even useful? // else - // error ("clear: no such function `%s'", name.c_str ()); + // error ("clear: no such function '%s'", name.c_str ()); } // This clears oct and mex files, incl. autoloads. @@ -1619,7 +1639,7 @@ fcn_table[alias] = finfo; } else - panic ("alias: `%s' is undefined", name.c_str ()); + panic ("alias: '%s' is undefined", name.c_str ()); } static void add_dispatch (const std::string& name, const std::string& type, @@ -1752,15 +1772,18 @@ inst->do_mark_global (name); } + // exclude: Storage classes to exclude, you can OR them together static std::list<symbol_record> all_variables (scope_id scope = xcurrent_scope, context_id context = xdefault_context, - bool defined_only = true) + bool defined_only = true, + unsigned int exclude = symbol_record::hidden) { symbol_table *inst = get_instance (scope); return inst - ? inst->do_all_variables (context, defined_only) : std::list<symbol_record> (); + ? inst->do_all_variables (context, defined_only, exclude) + : std::list<symbol_record> (); } static std::list<symbol_record> glob (const std::string& pattern) @@ -2110,6 +2133,9 @@ // The associated user code (may be null). octave_user_function *curr_fcn; + // If true then no variables can be added. + bool static_workspace; + // Map from names of global variables to values. static std::map<std::string, octave_value> global_table; @@ -2150,7 +2176,7 @@ symbol_table (scope_id scope) : my_scope (scope), table_name (), table (), nest_children (), nest_parent (0), - curr_fcn (0), persistent_table () { } + curr_fcn (0), static_workspace (false), persistent_table () { } ~symbol_table (void) { } @@ -2278,18 +2304,23 @@ octave_value do_builtin_find (const std::string& name); - symbol_record& do_insert (const std::string& name) + symbol_record& do_insert (const std::string& name, bool force_add = false) { table_iterator p = table.find (name); if (p == table.end ()) { - symbol_record parent_symbol; - - if (nest_parent && nest_parent->look_nonlocal (name, parent_symbol)) - return table[name] = parent_symbol; + symbol_record ret (my_scope, name); + + if (nest_parent && nest_parent->look_nonlocal (name, ret)) + return table[name] = ret; else - return table[name] = symbol_record (my_scope, name, octave_value ()); + { + if (static_workspace && ! force_add) + ret.mark_added_static (); + + return table[name] = ret; + } } else return p->second; @@ -2309,13 +2340,13 @@ p->second.force_variable (context); } - octave_value& do_varref (const std::string& name, context_id context) + octave_value& do_varref (const std::string& name, context_id context, bool force_add) { table_iterator p = table.find (name); if (p == table.end ()) { - symbol_record& sr = do_insert (name); + symbol_record& sr = do_insert (name, force_add); return sr.varref (context); } @@ -2510,7 +2541,8 @@ } std::list<symbol_record> - do_all_variables (context_id context, bool defined_only) const + do_all_variables (context_id context, bool defined_only, + unsigned int exclude) const { std::list<symbol_record> retval; @@ -2518,7 +2550,8 @@ { const symbol_record& sr = p->second; - if (defined_only && ! sr.is_defined (context)) + if ((defined_only && ! sr.is_defined (context)) + || (sr.xstorage_class () & exclude)) continue; retval.push_back (sr);
--- a/libinterp/interpfcn/sysdep.cc +++ b/libinterp/interpfcn/sysdep.cc @@ -69,6 +69,7 @@ #include "quit.h" #include "Cell.h" +#include "builtins.h" #include "defun.h" #include "error.h" #include "input.h" @@ -645,7 +646,7 @@ if (interactive || forced_interactive) { - feval ("drawnow"); + Fdrawnow (); int c = octave_kbhit (args.length () == 0); @@ -697,7 +698,7 @@ { if (! xisnan (dval)) { - feval ("drawnow"); + Fdrawnow (); if (xisinf (dval)) { @@ -713,7 +714,7 @@ } else { - feval ("drawnow"); + Fdrawnow (); flush_octave_stdout (); octave_kbhit (); } @@ -746,7 +747,7 @@ warning ("sleep: NaN is an invalid delay"); else { - feval ("drawnow"); + Fdrawnow (); octave_sleep (dval); } } @@ -786,7 +787,7 @@ warning ("usleep: NaN is an invalid delay"); else { - feval ("drawnow"); + Fdrawnow (); int delay = NINT (dval);
--- a/libinterp/interpfcn/toplev.cc +++ b/libinterp/interpfcn/toplev.cc @@ -653,7 +653,7 @@ { recover_from_exception (); std::cerr - << "error: memory exhausted or requested size too large for range of Octave's index type -- trying to return to prompt" + << "error: out of memory -- trying to return to prompt" << std::endl; } } @@ -817,7 +817,7 @@ retval(0) = cmd_status; } else - error ("unable to start subprocess for `%s'", cmd_str.c_str ()); + error ("unable to start subprocess for '%s'", cmd_str.c_str ()); return retval; } @@ -1249,10 +1249,10 @@ { false, "ARPACK_LDFLAGS", OCTAVE_CONF_ARPACK_LDFLAGS }, { false, "ARPACK_LIBS", OCTAVE_CONF_ARPACK_LIBS }, { false, "BLAS_LIBS", OCTAVE_CONF_BLAS_LIBS }, - { false, "CARBON_LIBS", OCTAVE_CONF_CARBON_LIBS }, { false, "CAMD_CPPFLAGS", OCTAVE_CONF_CAMD_CPPFLAGS }, { false, "CAMD_LDFLAGS", OCTAVE_CONF_CAMD_LDFLAGS }, { false, "CAMD_LIBS", OCTAVE_CONF_CAMD_LIBS }, + { false, "CARBON_LIBS", OCTAVE_CONF_CARBON_LIBS }, { false, "CC", OCTAVE_CONF_CC }, // FIXME: CC_VERSION is deprecated. Remove in version 3.12 { false, "CC_VERSION", OCTAVE_CONF_CC_VERSION }, @@ -1302,11 +1302,13 @@ { false, "FFTW3F_LIBS", OCTAVE_CONF_FFTW3F_LIBS }, { false, "FLIBS", OCTAVE_CONF_FLIBS }, { false, "FPICFLAG", OCTAVE_CONF_FPICFLAG }, + { false, "FT2_CFLAGS", OCTAVE_CONF_FT2_CFLAGS }, { false, "FT2_LIBS", OCTAVE_CONF_FT2_LIBS }, { false, "GLPK_CPPFLAGS", OCTAVE_CONF_GLPK_CPPFLAGS }, { false, "GLPK_LDFLAGS", OCTAVE_CONF_GLPK_LDFLAGS }, { false, "GLPK_LIBS", OCTAVE_CONF_GLPK_LIBS }, { false, "GNUPLOT", OCTAVE_CONF_GNUPLOT }, + { false, "GRAPHICS_CFLAGS", OCTAVE_CONF_GRAPHICS_CFLAGS }, { false, "GRAPHICS_LIBS", OCTAVE_CONF_GRAPHICS_LIBS }, { false, "HDF5_CPPFLAGS", OCTAVE_CONF_HDF5_CPPFLAGS }, { false, "HDF5_LDFLAGS", OCTAVE_CONF_HDF5_LDFLAGS }, @@ -1318,19 +1320,18 @@ { false, "LEX", OCTAVE_CONF_LEX }, { false, "LEXLIB", OCTAVE_CONF_LEXLIB }, { false, "LFLAGS", OCTAVE_CONF_LFLAGS }, - { false, "LIBCRUFT", OCTAVE_CONF_LIBCRUFT }, { false, "LIBEXT", OCTAVE_CONF_LIBEXT }, { false, "LIBFLAGS", OCTAVE_CONF_LIBFLAGS }, { false, "LIBOCTAVE", OCTAVE_CONF_LIBOCTAVE }, { false, "LIBOCTINTERP", OCTAVE_CONF_LIBOCTINTERP }, { false, "LIBS", OCTAVE_CONF_LIBS }, + { false, "LLVM_CPPFLAGS", OCTAVE_CONF_LLVM_CPPFLAGS }, + { false, "LLVM_LDFLAGS", OCTAVE_CONF_LLVM_LDFLAGS }, + { false, "LLVM_LIBS", OCTAVE_CONF_LLVM_LIBS }, { false, "LN_S", OCTAVE_CONF_LN_S }, { false, "MAGICK_CPPFLAGS", OCTAVE_CONF_MAGICK_CPPFLAGS }, { false, "MAGICK_LDFLAGS", OCTAVE_CONF_MAGICK_LDFLAGS }, { false, "MAGICK_LIBS", OCTAVE_CONF_MAGICK_LIBS }, - { false, "LLVM_CPPFLAGS", OCTAVE_CONF_LLVM_CPPFLAGS }, - { false, "LLVM_LDFLAGS", OCTAVE_CONF_LLVM_LDFLAGS }, - { false, "LLVM_LIBS", OCTAVE_CONF_LLVM_LIBS }, { false, "MKOCTFILE_DL_LDFLAGS", OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS }, { false, "OCTAVE_LINK_DEPS", OCTAVE_CONF_OCTAVE_LINK_DEPS }, { false, "OCTAVE_LINK_OPTS", OCTAVE_CONF_OCTAVE_LINK_OPTS }, @@ -1365,6 +1366,8 @@ { false, "UMFPACK_LDFLAGS", OCTAVE_CONF_UMFPACK_LDFLAGS }, { false, "UMFPACK_LIBS", OCTAVE_CONF_UMFPACK_LIBS }, { false, "USE_64_BIT_IDX_T", OCTAVE_CONF_USE_64_BIT_IDX_T }, + { false, "WARN_CFLAGS", OCTAVE_CONF_WARN_CFLAGS }, + { false, "WARN_CXXFLAGS", OCTAVE_CONF_WARN_CXXFLAGS }, { false, "X11_INCFLAGS", OCTAVE_CONF_X11_INCFLAGS }, { false, "X11_LIBS", OCTAVE_CONF_X11_LIBS }, { false, "XTRA_CFLAGS", OCTAVE_CONF_XTRA_CFLAGS }, @@ -1475,12 +1478,17 @@ if (! error_state) { - Cell c = m.contents (arg.c_str ()); + if (m.isfield (arg)) + { + Cell c = m.contents (arg); - if (c.is_empty ()) - error ("octave_config_info: no info for `%s'", arg.c_str ()); + if (c.is_empty ()) + error ("octave_config_info: no info for '%s'", arg.c_str ()); + else + retval = c(0); + } else - retval = c(0); + error ("octave_config_info: invalid parameter '%s'", arg.c_str ()); } } else if (nargin == 0) @@ -1516,11 +1524,11 @@ /* malloc (0) is unpredictable; avoid it. */ if (sz == 0) sz = 1; - p = malloc (sz); + p = gnulib::malloc (sz); while (p == 0) { (*__new_handler) (); - p = malloc (sz); + p = gnulib::malloc (sz); } if (debug_new_delete)
--- a/libinterp/interpfcn/utils.cc +++ b/libinterp/interpfcn/utils.cc @@ -99,19 +99,17 @@ @seealso{iskeyword, exist, who}\n\ @end deftypefn") { - octave_value retval; + octave_value retval = false; - int argc = args.length () + 1; - - string_vector argv = args.make_argv ("isvarname"); + int nargin = args.length (); - if (error_state) - return retval; - - if (argc == 2) - retval = valid_identifier (argv[1]) && ! is_keyword (argv[1]); - else + if (nargin != 1) print_usage (); + else if (args(0).is_string ()) + { + std::string varname = args(0).string_value (); + retval = valid_identifier (varname) && ! is_keyword (varname); + } return retval; } @@ -122,6 +120,7 @@ %!assert (isvarname ("_1"), true) %!assert (isvarname ("1foo"), false) %!assert (isvarname (""), false) +%!assert (isvarname (12), false) %!error isvarname () %!error isvarname ("foo", "bar"); @@ -630,8 +629,8 @@ break; default: - warning ("unrecognized escape sequence `\\%c' --\ - converting to `%c'", s[j], s[j]); + warning ("unrecognized escape sequence '\\%c' --\ + converting to '%c'", s[j], s[j]); retval[i] = s[j]; break; }
--- a/libinterp/interpfcn/variables.cc +++ b/libinterp/interpfcn/variables.cc @@ -109,7 +109,7 @@ } if (! ans && warn) - error ("%s: the symbol `%s' is not valid as a function", + error ("%s: the symbol '%s' is not valid as a function", warn_for.c_str (), fcn_name.c_str ()); return ans; @@ -167,7 +167,7 @@ if (! retval) { - error ("%s: `%s' is not valid as a function", + error ("%s: '%s' is not valid as a function", warn_for.c_str (), fname.c_str ()); return retval; } @@ -176,7 +176,7 @@ warn_for.c_str ()); } else - error ("%s: `%s' is not valid as a function", + error ("%s: '%s' is not valid as a function", warn_for.c_str (), fname.c_str ()); } else @@ -543,13 +543,13 @@ Check only for built-in functions.\n\ \n\ @item \"file\"\n\ -Check only for files.\n\ +Check only for files and directories.\n\ \n\ @item \"dir\"\n\ Check only for directories.\n\ @end table\n\ \n\ -@seealso{file_in_loadpath}\n\ +@seealso{file_in_loadpath, file_in_path, stat}\n\ @end deftypefn") { octave_value retval = false; @@ -608,7 +608,7 @@ octave_value val = symbol_table::global_varval (nm); if (val.is_undefined () && ! silent) - error ("get_global_value: undefined symbol `%s'", nm.c_str ()); + error ("get_global_value: undefined symbol '%s'", nm.c_str ()); return val; } @@ -625,7 +625,7 @@ octave_value val = symbol_table::top_level_varval (nm); if (val.is_undefined () && ! silent) - error ("get_top_level_value: undefined symbol `%s'", nm.c_str ()); + error ("get_top_level_value: undefined symbol '%s'", nm.c_str ()); return val; } @@ -1110,7 +1110,7 @@ break; default: - error ("whos_line_format: modifier `%c' unknown", + error ("whos_line_format: modifier '%c' unknown", param.modifier); os << std::setiosflags (std::ios::right) @@ -1160,7 +1160,7 @@ break; default: - error ("whos_line_format: command `%c' unknown", + error ("whos_line_format: command '%c' unknown", param.command); } @@ -1593,7 +1593,7 @@ else if (argv[i] == "global") global_only = true; else if (argv[i][0] == '-') - warning ("%s: unrecognized option `%s'", my_name.c_str (), + warning ("%s: unrecognized option '%s'", my_name.c_str (), argv[i].c_str ()); else break; @@ -1881,7 +1881,7 @@ } else { - symbol_table::varref (ans) = val; + symbol_table::force_varref (ans) = val; if (print) val.print_with_name (octave_stdout, ans); @@ -2340,8 +2340,8 @@ { if (argc == 1) { - do_clear_globals (argv, argc, 1); - do_clear_variables (argv, argc, 1); + do_clear_globals (argv, argc, true); + do_clear_variables (argv, argc, true); } else { @@ -2536,7 +2536,7 @@ return SET_INTERNAL_VARIABLE (whos_line_format); } -static std::string Vmissing_function_hook = "unimplemented"; +static std::string Vmissing_function_hook = "__unimplemented__"; DEFUN (missing_function_hook, args, nargout, "-*- texinfo -*-\n\ @@ -2559,16 +2559,21 @@ // Don't do this if we're handling errors. if (buffer_error_messages == 0 && ! Vmissing_function_hook.empty ()) { - // Ensure auto-restoration. - unwind_protect frame; - frame.protect_var (Vmissing_function_hook); - - // Clear the variable prior to calling the function. - const std::string func_name = Vmissing_function_hook; - Vmissing_function_hook.clear (); - - // Call. - feval (func_name, octave_value (name)); + octave_value val = symbol_table::find_function (Vmissing_function_hook); + + if (val.is_defined ()) + { + // Ensure auto-restoration. + unwind_protect frame; + frame.protect_var (Vmissing_function_hook); + + // Clear the variable prior to calling the function. + const std::string func_name = Vmissing_function_hook; + Vmissing_function_hook.clear (); + + // Call. + feval (func_name, octave_value (name)); + } } }
--- a/libinterp/interpfcn/variables.h +++ b/libinterp/interpfcn/variables.h @@ -136,7 +136,8 @@ extern OCTINTERP_API void bind_ans (const octave_value& val, bool print); extern OCTINTERP_API void -bind_internal_variable (const std::string& fname, const octave_value& val); +bind_internal_variable (const std::string& fname, + const octave_value& val) GCC_ATTR_DEPRECATED; extern OCTINTERP_API void mlock (void); extern OCTINTERP_API void munlock (const std::string&);
--- a/libinterp/mkbuiltins +++ b/libinterp/mkbuiltins @@ -18,21 +18,67 @@ # along with Octave; see the file COPYING. If not, see # <http://www.gnu.org/licenses/>. -if test $# -eq 0; then - echo "usage: mkbuiltins f1 f2 ..." 1>&2 +if test $# -lt 2; then + echo "usage: mkbuiltins --header|--source f1 f2 ..." 1>&2 exit 1 fi SED=${SED:-'sed'} -cat << \EOF +make_header=false +make_source=false +case "$1" in + --header) + make_header=true + shift + ;; + --source) + make_source=true + shift + ;; + *) + echo "mkbuiltins: unrecognized option: $1" 1>&2 + exit 1 + ;; +esac + +if $make_header; then + + cat << \EOF +// DO NOT EDIT! Generated automatically by mkbuiltins. + +#if !defined (octave_builtin_defun_decls_h) +#define octave_builtin_defun_decls_h 1 + +#include "oct-obj.h" + +#define DEFUN_DECL(name) \ + extern OCTINTERP_API octave_value_list \ + name (const octave_value_list& = octave_value_list (), int = 0); + +EOF + + $SED -n -e 's/ *\(XDEFUN\|XDEFCONSTFUN\)_INTERNAL *( *\([_A-Za-z][_A-Za-z0-9]*\) *,.*$/DEFUN_DECL (F\2);/p; s/^ *XDEFUNX_INTERNAL *( *"\([_A-Za-z][_A-Za-z0-9]*\)" *,.*$/DEFUN_DECL (F\1);/p' "$@" + + cat << \EOF + +#undef DEFUN_DECL + +#endif + +EOF + +else + + cat << \EOF // DO NOT EDIT! Generated automatically by mkbuiltins. #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif #include "defun.h" +#include "help.h" #include "oct-obj.h" #include "variables.h" #include "builtins.h" @@ -79,33 +125,37 @@ EOF -for arg -do - fcn=`echo "$arg" | $SED 's,.*/,,; s/\.df//; s/-/_/g;'` - echo "static void" - echo "install_${fcn}_fcns (void)" - echo "{" - cat "$arg" - echo "}" - echo "" -done + for arg + do + fcn=`echo "$arg" | $SED 's,.*/,,; s/\.df//; s/-/_/g;'` + echo "static void" + echo "install_${fcn}_fcns (void)" + echo "{" + cat "$arg" + echo "}" + echo "" + done -cat << \EOF + cat << \EOF void install_builtins (void) { EOF -for arg -do - fcn=`echo "$arg" | $SED 's,.*/,,; s/\.df//; s/-/_/g;'` - echo " install_${fcn}_fcns ();" -done + for arg + do + fcn=`echo "$arg" | $SED 's,.*/,,; s/\.df//; s/-/_/g;'` + echo " install_${fcn}_fcns ();" + done -cat << \EOF + cat << \EOF + + install_built_in_docstrings (); } EOF +fi + exit 0
--- a/libinterp/mkdefs +++ b/libinterp/mkdefs @@ -31,10 +31,10 @@ echo "// DO NOT EDIT! Generated automatically by mkdefs." case "$file" in $srcdir/*) - xsrcdir=`echo "$file" | sed "s,^$srcdir,src,"` + xsrcdir=`echo "$file" | sed "s,^$srcdir,libinterp,"` ;; *) - xsrcdir="src/$file" + xsrcdir="libinterp/$file" ;; esac echo " XDEFUN_FILE_NAME (\"$xsrcdir\")"
--- a/libinterp/mkops +++ b/libinterp/mkops @@ -24,7 +24,7 @@ // DO NOT EDIT! Generated automatically by mkops. #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif extern void install_base_type_conversions (void);
--- a/libinterp/oct-conf.in.h +++ b/libinterp/oct-conf.in.h @@ -214,6 +214,14 @@ #define OCTAVE_CONF_DL_LIBS %OCTAVE_CONF_DL_LIBS% #endif +#ifndef OCTAVE_CONF_ENABLE_DYNAMIC_LINKING +#define OCTAVE_CONF_ENABLE_DYNAMIC_LINKING %OCTAVE_CONF_ENABLE_DYNAMIC_LINKING% +#endif + +#ifndef OCTAVE_CONF_EXEEXT +#define OCTAVE_CONF_EXEEXT %OCTAVE_CONF_EXEEXT% +#endif + #ifndef OCTAVE_CONF_GCC_VERSION #define OCTAVE_CONF_GCC_VERSION %OCTAVE_CONF_GCC_VERSION% #endif @@ -222,10 +230,6 @@ #define OCTAVE_CONF_GXX_VERSION %OCTAVE_CONF_GXX_VERSION% #endif -#ifndef OCTAVE_CONF_EXEEXT -#define OCTAVE_CONF_EXEEXT %OCTAVE_CONF_EXEEXT% -#endif - #ifndef OCTAVE_CONF_F77 #define OCTAVE_CONF_F77 %OCTAVE_CONF_F77% #endif @@ -278,6 +282,10 @@ #define OCTAVE_CONF_FPICFLAG %OCTAVE_CONF_FPICFLAG% #endif +#ifndef OCTAVE_CONF_FT2_CFLAGS +#define OCTAVE_CONF_FT2_CFLAGS %OCTAVE_CONF_FT2_CFLAGS% +#endif + #ifndef OCTAVE_CONF_FT2_LIBS #define OCTAVE_CONF_FT2_LIBS %OCTAVE_CONF_FT2_LIBS% #endif @@ -298,6 +306,10 @@ #define OCTAVE_CONF_GNUPLOT %OCTAVE_CONF_GNUPLOT% #endif +#ifndef OCTAVE_CONF_GRAPHICS_CFLAGS +#define OCTAVE_CONF_GRAPHICS_CFLAGS %OCTAVE_CONF_GRAPHICS_CFLAGS% +#endif + #ifndef OCTAVE_CONF_GRAPHICS_LIBS #define OCTAVE_CONF_GRAPHICS_LIBS %OCTAVE_CONF_GRAPHICS_LIBS% #endif @@ -350,10 +362,6 @@ #define OCTAVE_CONF_LFLAGS %OCTAVE_CONF_LFLAGS% #endif -#ifndef OCTAVE_CONF_LIBCRUFT -#define OCTAVE_CONF_LIBCRUFT %OCTAVE_CONF_LIBCRUFT% -#endif - #ifndef OCTAVE_CONF_LIBEXT #define OCTAVE_CONF_LIBEXT %OCTAVE_CONF_LIBEXT% #endif @@ -554,8 +562,12 @@ #define OCTAVE_CONF_USE_64_BIT_IDX_T %OCTAVE_CONF_USE_64_BIT_IDX_T% #endif -#ifndef OCTAVE_CONF_ENABLE_DYNAMIC_LINKING -#define OCTAVE_CONF_ENABLE_DYNAMIC_LINKING %OCTAVE_CONF_ENABLE_DYNAMIC_LINKING% +#ifndef OCTAVE_CONF_WARN_CFLAGS +#define OCTAVE_CONF_WARN_CFLAGS %OCTAVE_CONF_WARN_CFLAGS% +#endif + +#ifndef OCTAVE_CONF_WARN_CXXFLAGS +#define OCTAVE_CONF_WARN_CXXFLAGS %OCTAVE_CONF_WARN_CXXFLAGS% #endif #ifndef OCTAVE_CONF_X11_INCFLAGS
--- a/libinterp/octave-value/module.mk +++ b/libinterp/octave-value/module.mk @@ -1,7 +1,7 @@ EXTRA_DIST += \ octave-value/module.mk -OV_INTTYPE_INCLUDES = \ +OV_INTTYPE_INC = \ octave-value/ov-base-int.h \ octave-value/ov-base-int.cc \ octave-value/ov-int-traits.h \ @@ -15,13 +15,13 @@ octave-value/ov-uint64.h \ octave-value/ov-uint8.h -OV_SPARSE_INCLUDES = \ +OV_SPARSE_INC = \ octave-value/ov-base-sparse.h \ octave-value/ov-bool-sparse.h \ octave-value/ov-cx-sparse.h \ octave-value/ov-re-sparse.h -OV_INCLUDES = \ +OCTAVE_VALUE_INC = \ octave-value/ov-base-diag.h \ octave-value/ov-base-diag.cc \ octave-value/ov-base-mat.h \ @@ -67,7 +67,8 @@ octave-value/ov-typeinfo.h \ octave-value/ov-usr-fcn.h \ octave-value/ov.h \ - $(OV_INTTYPE_INCLUDES) + $(OV_INTTYPE_INC) \ + $(OV_SPARSE_INC) OV_INTTYPE_SRC = \ octave-value/ov-int16.cc \ @@ -129,3 +130,4 @@ noinst_LTLIBRARIES += octave-value/liboctave-value.la octave_value_liboctave_value_la_SOURCES = $(OCTAVE_VALUE_SRC) +octave_value_liboctave_value_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS)
--- a/libinterp/octave-value/ov-base-diag.cc +++ b/libinterp/octave-value/ov-base-diag.cc @@ -68,6 +68,32 @@ return retval.next_subsref (type, idx); } + +template <class DMT, class MT> +octave_value +octave_base_diag<DMT,MT>::diag (octave_idx_type k) const +{ + octave_value retval; + if (matrix.rows () == 1 || matrix.cols () == 1) + { + // Rather odd special case. This is a row or column vector + // represented as a diagonal matrix with a single nonzero entry, but + // Fdiag semantics are to product a diagonal matrix for vector + // inputs. + if (k == 0) + // Returns Diag2Array<T> with nnz <= 1. + retval = matrix.build_diag_matrix (); + else + // Returns Array<T> matrix + retval = matrix.array_value ().diag (k); + } + else + // Returns Array<T> vector + retval = matrix.extract_diag (k); + return retval; +} + + template <class DMT, class MT> octave_value octave_base_diag<DMT, MT>::do_index_op (const octave_value_list& idx, @@ -122,7 +148,7 @@ { octave_value_list jdx = idx.front (); // Check for a simple element assignment. That means, if D is a diagonal matrix, - // `D(i,i) = x' will not destroy its diagonality (provided i is a valid index). + // 'D(i,i) = x' will not destroy its diagonality (provided i is a valid index). if (jdx.length () == 2 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ()) { typename DMT::element_type val; @@ -400,7 +426,7 @@ os << "# rows: " << matrix.rows () << "\n" << "# columns: " << matrix.columns () << "\n"; - os << matrix.diag (); + os << matrix.extract_diag (); return true; }
--- a/libinterp/octave-value/ov-base-diag.h +++ b/libinterp/octave-value/ov-base-diag.h @@ -97,8 +97,7 @@ MatrixType matrix_type (const MatrixType&) const { return matrix_type (); } - octave_value diag (octave_idx_type k = 0) const - { return octave_value (matrix.diag (k)); } + octave_value diag (octave_idx_type k = 0) const; octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const { return to_dense ().sort (dim, mode); }
--- a/libinterp/octave-value/ov-base.cc +++ b/libinterp/octave-value/ov-base.cc @@ -1193,6 +1193,7 @@ "erfinv", "erfcinv", "erfc", + "erfcx", "exp", "expm1", "finite", @@ -1229,6 +1230,7 @@ "isspace", "isupper", "isxdigit", + "signbit", "toascii", "tolower", "toupper" @@ -1272,7 +1274,7 @@ static void gripe_indexed_assignment (const std::string& tn1, const std::string& tn2) { - error ("assignment of `%s' to indexed `%s' not implemented", + error ("assignment of '%s' to indexed '%s' not implemented", tn2.c_str (), tn1.c_str ()); } @@ -1280,7 +1282,7 @@ gripe_assign_conversion_failed (const std::string& tn1, const std::string& tn2) { - error ("type conversion for assignment of `%s' to indexed `%s' failed", + error ("type conversion for assignment of '%s' to indexed '%s' failed", tn2.c_str (), tn1.c_str ()); } @@ -1288,7 +1290,7 @@ gripe_no_conversion (const std::string& on, const std::string& tn1, const std::string& tn2) { - error ("operator %s: no conversion for assignment of `%s' to indexed `%s'", + error ("operator %s: no conversion for assignment of '%s' to indexed '%s'", on.c_str (), tn2.c_str (), tn1.c_str ()); }
--- a/libinterp/octave-value/ov-base.h +++ b/libinterp/octave-value/ov-base.h @@ -725,6 +725,7 @@ umap_xisspace, umap_xisupper, umap_xisxdigit, + umap_xsignbit, umap_xtoascii, umap_xtolower, umap_xtoupper, @@ -801,9 +802,9 @@ // (think of an empty cell array with >2G elements). octave_refcount<octave_idx_type> count; -private: + static const char *get_umap_name (unary_mapper_t); - static const char *get_umap_name (unary_mapper_t); +private: static int curr_print_indent_level; static bool beginning_of_line;
--- a/libinterp/octave-value/ov-ch-mat.cc +++ b/libinterp/octave-value/ov-ch-mat.cc @@ -152,21 +152,28 @@ return retval; } -// The C++ standard guarantees cctype defines functions, not macros (and hence macros *CAN'T* -// be defined if only cctype is included) -// so there's no need to f*ck around. The exceptions are isascii and toascii, -// which are not C++. -// Oddly enough, all those character functions are int (*) (int), even -// in C++. Wicked! +// The C++ standard guarantees cctype defines functions, not macros (and +// hence macros *CAN'T* be defined if only cctype is included) so +// there's no need to fuck around. The exceptions are isascii and +// toascii, which are not C++. Oddly enough, all those character +// functions are int (*) (int), even in C++. Wicked! static inline int xisascii (int c) { return isascii (c); } static inline int xtoascii (int c) -{ return toascii (c); } +{ +#ifdef HAVE_TOASCII + return toascii (c); +#else + return (c & 0x7F); +#endif +} octave_value octave_char_matrix::map (unary_mapper_t umap) const { + octave_value retval; + switch (umap) { #define STRING_MAPPER(UMAP,FCN,TYPE) \ @@ -189,10 +196,26 @@ STRING_MAPPER (xtolower, std::tolower, char); STRING_MAPPER (xtoupper, std::toupper, char); - default: + // For Matlab compatibility, these should work on ASCII values + // without error or warning. + case umap_abs: + case umap_ceil: + case umap_fix: + case umap_floor: + case umap_imag: + case umap_isinf: + case umap_isnan: + case umap_real: + case umap_round: { octave_matrix m (array_value (true)); return m.map (umap); } + + default: + error ("%s: expecting numeric argument", get_umap_name (umap)); + break; } + + return retval; }
--- a/libinterp/octave-value/ov-class.cc +++ b/libinterp/octave-value/ov-class.cc @@ -324,13 +324,13 @@ subs_field(i) = val; else { - error ("expecting character string argument for `.' index"); + error ("expecting character string argument for '.' index"); return retval; } } else { - error ("expecting single argument for `.' index"); + error ("expecting single argument for '.' index"); return retval; } } @@ -386,7 +386,7 @@ if (p != my_map.end ()) retval = my_map.contents (p); else - error ("class has no member `%s'", nm.c_str ()); + error ("class has no member '%s'", nm.c_str ()); } else gripe_invalid_index1 (); @@ -1975,7 +1975,7 @@ octave_class::exemplar_map[id] = octave_class::exemplar_info (retval); else if (! it->second.compare (retval)) - error ("class: object of class `%s' does not match previously constructed objects", + error ("class: object of class '%s' does not match previously constructed objects", id.c_str ()); } } @@ -1983,7 +1983,7 @@ error ("class: expecting structure S as first argument"); } else - error ("class: `%s' is invalid as a class name in this context", + error ("class: '%s' is invalid as a class name in this context", id.c_str ()); } else
--- a/libinterp/octave-value/ov-colon.h +++ b/libinterp/octave-value/ov-colon.h @@ -39,7 +39,7 @@ class tree_walker; -// A type to represent `:' as used for indexing. +// A type to represent ':' as used for indexing. class octave_magic_colon : public octave_base_value
--- a/libinterp/octave-value/ov-cx-diag.cc +++ b/libinterp/octave-value/ov-cx-diag.cc @@ -149,7 +149,7 @@ return ::imag (matrix); case umap_sqrt: { - ComplexColumnVector tmp = matrix.diag ().map<Complex> (std::sqrt); + ComplexColumnVector tmp = matrix.extract_diag ().map<Complex> (std::sqrt); ComplexDiagMatrix retval (tmp); retval.resize (matrix.rows (), matrix.columns ()); return retval; @@ -167,7 +167,7 @@ os.write (reinterpret_cast<char *> (&r), 4); os.write (reinterpret_cast<char *> (&c), 4); - ComplexMatrix m = ComplexMatrix (matrix.diag ()); + ComplexMatrix m = ComplexMatrix (matrix.extract_diag ()); save_type st = LS_DOUBLE; if (save_as_floats) {
--- a/libinterp/octave-value/ov-fcn-handle.cc +++ b/libinterp/octave-value/ov-fcn-handle.cc @@ -375,7 +375,7 @@ for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); p != vars.end (); p++) { - if (! save_ascii_data (os, p->varval (), p->name (), false, 0)) + if (! save_ascii_data (os, p->varval (0), p->name (), false, 0)) return os; } } @@ -550,7 +550,7 @@ for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); p != vars.end (); p++) { - if (! save_binary_data (os, p->varval (), p->name (), + if (! save_binary_data (os, p->varval (0), p->name (), "", 0, save_as_floats)) return os; } @@ -839,7 +839,7 @@ for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); p != vars.end (); p++) { - if (! add_hdf5_data (data_hid, p->varval (), p->name (), + if (! add_hdf5_data (data_hid, p->varval (0), p->name (), "", false, save_as_floats)) break; } @@ -1311,6 +1311,7 @@ %! mode = modes{i}; %! nm = tmpnam (); %! unwind_protect +%! f2 (1); # bug #33857 %! save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2"); %! clear f2 g2 hm2 hdld2 hbi2 %! load (nm); @@ -1325,6 +1326,58 @@ %! endfor */ +/* +%!function fcn_handle_save_recurse (n, mode, nm, f2, g2, hm2, hdld2, hbi2) +%! if n == 0 +%! save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2"); +%! else +%! fcn_handle_save_recurse (n - 1, mode, nm, f2, g2, hm2, hdld2, hbi2); +%! endif +%!endfunction +%!function [f2, g2, hm2, hdld2, hbi2] = fcn_handle_load_recurse (n, nm) +%! if n == 0 +%! load (nm) +%! else +%! [f2, g2, hm2, hdld2, hbi2] = fcn_handle_load_recurse (n - 1, nm); +%! endif +%!endfunction + +Test for bug #35876 +%!test +%! a = 2; +%! f = @(x) a + x; +%! g = @(x) 2 * x; +%! hm = @version; +%! hdld = @svd; +%! hbi = @log2; +%! f2 = f; +%! g2 = g; +%! hm2 = hm; +%! hdld2 = hdld; +%! hbi2 = hbi; +%! modes = {"-text", "-binary"}; +%! if (!isempty (findstr (octave_config_info ("DEFS"), "HAVE_HDF5"))) +%! modes(end+1) = "-hdf5"; +%! endif +%! for i = 1:numel (modes) +%! mode = modes{i}; +%! nm = tmpnam (); +%! unwind_protect +%! fcn_handle_save_recurse (2, mode, nm, f2, g2, hm2, hdld2, hbi2); +%! clear f2 g2 hm2 hdld2 hbi2 +%! [f2, f2, hm2, hdld2, hbi2] = fcn_handle_load_recurse (2, nm); +%! load (nm); +%! assert (f (2), f2 (2)); +%! assert (g (2), g2 (2)); +%! assert (g (3), g2 (3)); +%! unlink (nm); +%! fcn_handle_save_recurse (2, mode, nm, f2, g2, hm2, hdld2, hbi2); +%! unwind_protect_cleanup +%! unlink (nm); +%! end_unwind_protect +%! endfor +*/ + void octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax) const {
--- a/libinterp/octave-value/ov-float.cc +++ b/libinterp/octave-value/ov-float.cc @@ -321,6 +321,7 @@ SCALAR_MAPPER (isinf, xisinf); SCALAR_MAPPER (isna, octave_is_NA); SCALAR_MAPPER (isnan, xisnan); + SCALAR_MAPPER (xsignbit, xsignbit); default: return octave_base_value::map (umap);
--- a/libinterp/octave-value/ov-flt-cx-diag.cc +++ b/libinterp/octave-value/ov-flt-cx-diag.cc @@ -133,7 +133,7 @@ return ::imag (matrix); case umap_sqrt: { - FloatComplexColumnVector tmp = matrix.diag ().map<FloatComplex> (std::sqrt); + FloatComplexColumnVector tmp = matrix.extract_diag ().map<FloatComplex> (std::sqrt); FloatComplexDiagMatrix retval (tmp); retval.resize (matrix.rows (), matrix.columns ()); return retval; @@ -153,7 +153,7 @@ os.write (reinterpret_cast<char *> (&r), 4); os.write (reinterpret_cast<char *> (&c), 4); - FloatComplexMatrix m = FloatComplexMatrix (matrix.diag ()); + FloatComplexMatrix m = FloatComplexMatrix (matrix.extract_diag ()); save_type st = LS_FLOAT; if (matrix.length () > 4096) // FIXME -- make this configurable. {
--- a/libinterp/octave-value/ov-flt-re-diag.cc +++ b/libinterp/octave-value/ov-flt-re-diag.cc @@ -103,7 +103,7 @@ return DiagMatrix (matrix.rows (), matrix.cols (), 0.0); case umap_sqrt: { - FloatComplexColumnVector tmp = matrix.diag ().map<FloatComplex> (rc_sqrt); + FloatComplexColumnVector tmp = matrix.extract_diag ().map<FloatComplex> (rc_sqrt); FloatComplexDiagMatrix retval (tmp); retval.resize (matrix.rows (), matrix.columns ()); return retval; @@ -122,7 +122,7 @@ os.write (reinterpret_cast<char *> (&r), 4); os.write (reinterpret_cast<char *> (&c), 4); - FloatMatrix m = FloatMatrix (matrix.diag ()); + FloatMatrix m = FloatMatrix (matrix.extract_diag ()); save_type st = LS_FLOAT; if (matrix.length () > 8192) // FIXME -- make this configurable. {
--- a/libinterp/octave-value/ov-flt-re-mat.cc +++ b/libinterp/octave-value/ov-flt-re-mat.cc @@ -806,6 +806,7 @@ ARRAY_MAPPER (tan, float, ::tanf); ARRAY_MAPPER (tanh, float, ::tanhf); ARRAY_MAPPER (isna, bool, octave_is_NA); + ARRAY_MAPPER (xsignbit, float, xsignbit); default: return octave_base_value::map (umap);
--- a/libinterp/octave-value/ov-oncleanup.cc +++ b/libinterp/octave-value/ov-oncleanup.cc @@ -92,11 +92,6 @@ // Swallow the interrupt. warning ("onCleanup: interrupt occured in cleanup action"); } - catch (std::bad_alloc) - { - // Swallow the exception. - warning ("onCleanup: out of memory occured in cleanup action"); - } catch (...) // Yes, the black hole. We're in a d-tor. { // This shouldn't happen, in theory. @@ -108,7 +103,7 @@ // Otherwise, set it back to what it was before. if (error_state) { - frame.discard_top (); + frame.discard_first (); octave_call_stack::backtrace_error_message (); } }
--- a/libinterp/octave-value/ov-re-diag.cc +++ b/libinterp/octave-value/ov-re-diag.cc @@ -163,7 +163,7 @@ return DiagMatrix (matrix.rows (), matrix.cols (), 0.0); case umap_sqrt: { - ComplexColumnVector tmp = matrix.diag ().map<Complex> (rc_sqrt); + ComplexColumnVector tmp = matrix.extract_diag ().map<Complex> (rc_sqrt); ComplexDiagMatrix retval (tmp); retval.resize (matrix.rows (), matrix.columns ()); return retval; @@ -181,7 +181,7 @@ os.write (reinterpret_cast<char *> (&r), 4); os.write (reinterpret_cast<char *> (&c), 4); - Matrix m = Matrix (matrix.diag ()); + Matrix m = Matrix (matrix.extract_diag ()); save_type st = LS_DOUBLE; if (save_as_floats) {
--- a/libinterp/octave-value/ov-re-mat.cc +++ b/libinterp/octave-value/ov-re-mat.cc @@ -929,6 +929,7 @@ ARRAY_MAPPER (tan, double, ::tan); ARRAY_MAPPER (tanh, double, ::tanh); ARRAY_MAPPER (isna, bool, octave_is_NA); + ARRAY_MAPPER (xsignbit, double, xsignbit); default: if (umap >= umap_xisalnum && umap <= umap_xtoupper)
--- a/libinterp/octave-value/ov-scalar.cc +++ b/libinterp/octave-value/ov-scalar.cc @@ -337,6 +337,7 @@ SCALAR_MAPPER (isinf, xisinf); SCALAR_MAPPER (isna, octave_is_NA); SCALAR_MAPPER (isnan, xisnan); + SCALAR_MAPPER (xsignbit, xsignbit); default: if (umap >= umap_xisalnum && umap <= umap_xtoupper)
--- a/libinterp/octave-value/ov-struct.cc +++ b/libinterp/octave-value/ov-struct.cc @@ -85,7 +85,7 @@ else if (auto_add) retval = (numel () == 0) ? Cell (dim_vector (1, 1)) : Cell (dims ()); else - error ("structure has no member `%s'", nm.c_str ()); + error ("structure has no member '%s'", nm.c_str ()); return retval; } @@ -1100,7 +1100,7 @@ octave_value retval = map.getfield (nm); if (! auto_add && retval.is_undefined ()) - error ("structure has no member `%s'", nm.c_str ()); + error ("structure has no member '%s'", nm.c_str ()); return retval; } @@ -1807,7 +1807,7 @@ if (! valid_identifier (key)) { - error ("struct: invalid structure field name `%s'", key.c_str ()); + error ("struct: invalid structure field name '%s'", key.c_str ()); return retval; } @@ -2144,10 +2144,11 @@ DEFUN (rmfield, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} rmfield (@var{s}, @var{f})\n\ +@deftypefn {Built-in Function} {@var{s} =} rmfield (@var{s}, \"@var{f}\")\n\ +@deftypefnx {Built-in Function} {@var{s} =} rmfield (@var{s}, @var{f})\n\ Return a copy of the structure (array) @var{s} with the field @var{f}\n\ removed. If @var{f} is a cell array of strings or a character array, remove\n\ -the named fields.\n\ +each of the named fields.\n\ @seealso{cellstr, iscellstr, setfield}\n\ @end deftypefn") { @@ -2192,8 +2193,14 @@ /* ## test rmfield +%!shared x +%! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; x(6).f="abc123"; +%! %!test -%! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; x(6).f="abc123"; +%! y = rmfield (x, "c"); +%! assert (fieldnames (y), {"d"; "a"; "b"; "f"}); +%! assert (size (y), [1, 6]); +%!test %! y = rmfield (x, {"a", "f"}); %! assert (fieldnames (y), {"d"; "b"; "c"}); %! assert (size (y), [1, 6]);
--- a/libinterp/octave-value/ov-typeinfo.cc +++ b/libinterp/octave-value/ov-typeinfo.cc @@ -243,7 +243,7 @@ { std::string op_name = octave_value::unary_op_as_string (op); - warning ("duplicate unary operator `%s' for class dispatch", + warning ("duplicate unary operator '%s' for class dispatch", op_name.c_str ()); } @@ -261,7 +261,7 @@ std::string op_name = octave_value::unary_op_as_string (op); std::string type_name = types(t); - warning ("duplicate unary operator `%s' for type `%s'", + warning ("duplicate unary operator '%s' for type '%s'", op_name.c_str (), type_name.c_str ()); } @@ -279,7 +279,7 @@ std::string op_name = octave_value::unary_op_as_string (op); std::string type_name = types(t); - warning ("duplicate unary operator `%s' for type `%s'", + warning ("duplicate unary operator '%s' for type '%s'", op_name.c_str (), type_name.c_str ()); } @@ -296,7 +296,7 @@ { std::string op_name = octave_value::binary_op_as_string (op); - warning ("duplicate binary operator `%s' for class dispatch", + warning ("duplicate binary operator '%s' for class dispatch", op_name.c_str ()); } @@ -316,7 +316,7 @@ std::string t1_name = types(t1); std::string t2_name = types(t2); - warning ("duplicate binary operator `%s' for types `%s' and `%s'", + warning ("duplicate binary operator '%s' for types '%s' and '%s'", op_name.c_str (), t1_name.c_str (), t1_name.c_str ()); } @@ -333,7 +333,7 @@ { std::string op_name = octave_value::binary_op_fcn_name (op); - warning ("duplicate compound binary operator `%s' for class dispatch", + warning ("duplicate compound binary operator '%s' for class dispatch", op_name.c_str ()); } @@ -353,7 +353,7 @@ std::string t1_name = types(t1); std::string t2_name = types(t2); - warning ("duplicate compound binary operator `%s' for types `%s' and `%s'", + warning ("duplicate compound binary operator '%s' for types '%s' and '%s'", op_name.c_str (), t1_name.c_str (), t1_name.c_str ()); } @@ -370,7 +370,7 @@ std::string t1_name = types(t1); std::string t2_name = types(t2); - warning ("duplicate concatenation operator for types `%s' and `%s'", + warning ("duplicate concatenation operator for types '%s' and '%s'", t1_name.c_str (), t1_name.c_str ()); } @@ -390,7 +390,7 @@ std::string t_lhs_name = types(t_lhs); std::string t_rhs_name = types(t_rhs); - warning ("duplicate assignment operator `%s' for types `%s' and `%s'", + warning ("duplicate assignment operator '%s' for types '%s' and '%s'", op_name.c_str (), t_lhs_name.c_str (), t_rhs_name.c_str ()); } @@ -408,7 +408,7 @@ std::string op_name = octave_value::assign_op_as_string (op); std::string t_lhs_name = types(t_lhs); - warning ("duplicate assignment operator `%s' for types `%s'", + warning ("duplicate assignment operator '%s' for types '%s'", op_name.c_str (), t_lhs_name.c_str ()); } @@ -426,7 +426,7 @@ std::string t_lhs_name = types(t_lhs); std::string t_rhs_name = types(t_rhs); - warning ("overriding assignment conversion for types `%s' and `%s'", + warning ("overriding assignment conversion for types '%s' and '%s'", t_lhs_name.c_str (), t_rhs_name.c_str ()); } @@ -444,7 +444,7 @@ std::string t_name = types(t); std::string t_result_name = types(t_result); - warning ("overriding type conversion op for `%s' to `%s'", + warning ("overriding type conversion op for '%s' to '%s'", t_name.c_str (), t_result_name.c_str ()); } @@ -462,7 +462,7 @@ std::string t_name = types(t); std::string t_result_name = types(t_result); - warning ("overriding widening op for `%s' to `%s'", + warning ("overriding widening op for '%s' to '%s'", t_name.c_str (), t_result_name.c_str ()); }
--- a/libinterp/octave-value/ov-usr-fcn.cc +++ b/libinterp/octave-value/ov-usr-fcn.cc @@ -30,6 +30,7 @@ #include <defaults.h> #include "Cell.h" +#include "builtins.h" #include "defun.h" #include "error.h" #include "gripes.h" @@ -39,6 +40,7 @@ #include "ov.h" #include "pager.h" #include "pt-eval.h" +#include "pt-jit.h" #include "pt-jump.h" #include "pt-misc.h" #include "pt-pr-code.h" @@ -192,6 +194,9 @@ class_constructor (false), class_method (false), parent_scope (-1), local_scope (sid), curr_unwind_protect_frame (0) +#ifdef HAVE_LLVM + , jit_info (0) +#endif { if (cmd_list) cmd_list->mark_as_function_body (); @@ -208,6 +213,10 @@ delete lead_comm; delete trail_comm; +#ifdef HAVE_LLVM + delete jit_info; +#endif + symbol_table::erase_scope (local_scope); } @@ -372,6 +381,12 @@ if (! cmd_list) return retval; +#ifdef HAVE_LLVM + if (Venable_jit_compiler && is_special_expr () + && tree_jit::execute (*this, args, retval)) + return retval; +#endif + int nargin = args.length (); unwind_protect frame; @@ -441,6 +456,8 @@ bind_automatic_vars (arg_names, nargin, nargout, all_va_args (args), lvalue_list); + frame.add_method (this, &octave_user_function::restore_warning_states); + bool echo_commands = (Vecho_executing_commands & ECHO_FUNCTIONS); if (echo_commands) @@ -457,23 +474,14 @@ frame.protect_var (tree_evaluator::statement_context); tree_evaluator::statement_context = tree_evaluator::function; - bool special_expr = (is_inline_function () || is_anonymous_function ()); - BEGIN_PROFILER_BLOCK (profiler_name ()) - if (special_expr) + if (is_special_expr ()) { - assert (cmd_list->length () == 1); - - tree_statement *stmt = 0; + tree_expression *expr = special_expr (); - if ((stmt = cmd_list->front ()) - && stmt->is_expression ()) - { - tree_expression *expr = stmt->expression (); - - retval = expr->rvalue (nargout); - } + if (expr) + retval = expr->rvalue (nargout); } else cmd_list->accept (*current_evaluator); @@ -497,7 +505,7 @@ // Copy return values out. - if (ret_list && ! special_expr) + if (ret_list && ! is_special_expr ()) { ret_list->initialize_undefined_elements (my_name, nargout, Matrix ()); @@ -529,6 +537,16 @@ tw.visit_octave_user_function (*this); } +tree_expression * +octave_user_function::special_expr (void) +{ + assert (is_special_expr ()); + assert (cmd_list->length () == 1); + + tree_statement *stmt = cmd_list->front (); + return stmt->expression (); +} + bool octave_user_function::subsasgn_optimization_ok (void) { @@ -581,8 +599,8 @@ // which might be redefined in a function. Keep the old argn name // for backward compatibility of functions that use it directly. - symbol_table::varref ("argn") = arg_names; - symbol_table::varref (".argn.") = Cell (arg_names); + symbol_table::force_varref ("argn") = arg_names; + symbol_table::force_varref (".argn.") = Cell (arg_names); symbol_table::mark_hidden (".argn."); @@ -590,8 +608,8 @@ symbol_table::mark_automatic (".argn."); } - symbol_table::varref (".nargin.") = nargin; - symbol_table::varref (".nargout.") = nargout; + symbol_table::force_varref (".nargin.") = nargin; + symbol_table::force_varref (".nargout.") = nargout; symbol_table::mark_hidden (".nargin."); symbol_table::mark_hidden (".nargout."); @@ -599,6 +617,11 @@ symbol_table::mark_automatic (".nargin."); symbol_table::mark_automatic (".nargout."); + symbol_table::varref (".saved_warning_states.") = octave_value (); + + symbol_table::mark_automatic (".saved_warning_states."); + symbol_table::mark_automatic (".saved_warning_states."); + if (takes_varargs ()) symbol_table::varref ("varargin") = va_args.cell_value (); @@ -633,6 +656,26 @@ symbol_table::mark_automatic (".ignored."); } +void +octave_user_function::restore_warning_states (void) +{ + octave_value val = symbol_table::varval (".saved_warning_states."); + + if (val.is_defined ()) + { + octave_map m = val.map_value (); + + if (error_state) + panic_impossible (); + + Cell ids = m.contents ("identifier"); + Cell states = m.contents ("state"); + + for (octave_idx_type i = 0; i < m.numel (); i++) + Fwarning (ovl (states(i), ids(i))); + } +} + DEFUN (nargin, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} nargin ()\n\
--- a/libinterp/octave-value/ov-usr-fcn.h +++ b/libinterp/octave-value/ov-usr-fcn.h @@ -41,8 +41,13 @@ class tree_parameter_list; class tree_statement_list; class tree_va_return_list; +class tree_expression; class tree_walker; +#ifdef HAVE_LLVM +class jit_function_info; +#endif + class octave_user_code : public octave_function { @@ -283,6 +288,14 @@ : false; } + // If we are a special expression, then the function body consists of exactly + // one expression. The expression's result is the return value of the + // function. + bool is_special_expr (void) const + { + return is_inline_function () || is_anonymous_function (); + } + bool is_nested_function (void) const { return nested_function; } void mark_as_nested_function (void) { nested_function = true; } @@ -335,6 +348,10 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + // If is_special_expr is true, retrieve the sigular expression that forms the + // body. May be null (even if is_special_expr is true). + tree_expression *special_expr (void); + bool subsasgn_optimization_ok (void); void accept (tree_walker& tw); @@ -351,6 +368,12 @@ return false; } +#ifdef HAVE_LLVM + jit_function_info *get_info (void) { return jit_info; } + + void stash_info (jit_function_info *info) { jit_info = info; } +#endif + #if 0 void print_symtab_info (std::ostream& os) const; #endif @@ -427,6 +450,10 @@ // pointer to the current unwind_protect frame of this function. unwind_protect *curr_unwind_protect_frame; +#ifdef HAVE_LLVM + jit_function_info *jit_info; +#endif + #if 0 // The symbol record for argn in the local symbol table. octave_value& argn_varref; @@ -449,6 +476,8 @@ int nargout, const octave_value_list& va_args, const std::list<octave_lvalue> *lvalue_list); + void restore_warning_states (void); + // No copying! octave_user_function (const octave_user_function& fn);
--- a/libinterp/octave-value/ov.cc +++ b/libinterp/octave-value/ov.cc @@ -670,6 +670,30 @@ maybe_mutate (); } +octave_value::octave_value (const DiagArray2<double>& d) + : rep (new octave_diag_matrix (d)) +{ + maybe_mutate (); +} + +octave_value::octave_value (const DiagArray2<float>& d) + : rep (new octave_float_diag_matrix (d)) +{ + maybe_mutate (); +} + +octave_value::octave_value (const DiagArray2<Complex>& d) + : rep (new octave_complex_diag_matrix (d)) +{ + maybe_mutate (); +} + +octave_value::octave_value (const DiagArray2<FloatComplex>& d) + : rep (new octave_float_complex_diag_matrix (d)) +{ + maybe_mutate (); +} + octave_value::octave_value (const DiagMatrix& d) : rep (new octave_diag_matrix (d)) { @@ -1320,7 +1344,7 @@ gripe_assign_failed (const std::string& on, const std::string& tn1, const std::string& tn2) { - error ("assignment failed for `%s %s %s'", + error ("assignment failed for '%s %s %s'", tn1.c_str (), on.c_str (), tn2.c_str ()); } #endif @@ -1330,7 +1354,7 @@ const std::string& tn1, const std::string& tn2) { - error ("assignment failed, or no method for `%s %s %s'", + error ("assignment failed, or no method for '%s %s %s'", tn1.c_str (), on.c_str (), tn2.c_str ()); } @@ -1888,14 +1912,14 @@ gripe_binary_op (const std::string& on, const std::string& tn1, const std::string& tn2) { - error ("binary operator `%s' not implemented for `%s' by `%s' operations", + error ("binary operator '%s' not implemented for '%s' by '%s' operations", on.c_str (), tn1.c_str (), tn2.c_str ()); } static void gripe_binary_op_conv (const std::string& on) { - error ("type conversion failed for binary operator `%s'", on.c_str ()); + error ("type conversion failed for binary operator '%s'", on.c_str ()); } octave_value @@ -2200,7 +2224,7 @@ static void gripe_cat_op (const std::string& tn1, const std::string& tn2) { - error ("concatenation operator not implemented for `%s' by `%s' operations", + error ("concatenation operator not implemented for '%s' by '%s' operations", tn1.c_str (), tn2.c_str ()); } @@ -2312,14 +2336,14 @@ static void gripe_unary_op (const std::string& on, const std::string& tn) { - error ("unary operator `%s' not implemented for `%s' operands", + error ("unary operator '%s' not implemented for '%s' operands", on.c_str (), tn.c_str ()); } static void gripe_unary_op_conv (const std::string& on) { - error ("type conversion failed for unary operator `%s'", on.c_str ()); + error ("type conversion failed for unary operator '%s'", on.c_str ()); } octave_value @@ -2399,7 +2423,7 @@ gripe_unary_op_conversion_failed (const std::string& op, const std::string& tn) { - error ("operator %s: type conversion for `%s' failed", + error ("operator %s: type conversion for '%s' failed", op.c_str (), tn.c_str ()); } @@ -2791,7 +2815,7 @@ type_string[k] = '.'; else { - error ("%s: invalid indexing type `%s'", name, item.c_str ()); + error ("%s: invalid indexing type '%s'", name, item.c_str ()); return; } } @@ -2830,7 +2854,7 @@ } } else - error ("%s: second argument must be a structure with fields `type' and `subs'", name); + error ("%s: second argument must be a structure with fields 'type' and 'subs'", name); } DEFUN (subsref, args, nargout,
--- a/libinterp/octave-value/ov.h +++ b/libinterp/octave-value/ov.h @@ -203,6 +203,10 @@ octave_value (const Array<double>& m); octave_value (const Array<float>& m); octave_value (const DiagMatrix& d); + octave_value (const DiagArray2<double>& d); + octave_value (const DiagArray2<float>& d); + octave_value (const DiagArray2<Complex>& d); + octave_value (const DiagArray2<FloatComplex>& d); octave_value (const FloatDiagMatrix& d); octave_value (const RowVector& v); octave_value (const FloatRowVector& v); @@ -1162,6 +1166,7 @@ MAPPER_FORWARD (xisspace) MAPPER_FORWARD (xisupper) MAPPER_FORWARD (xisxdigit) + MAPPER_FORWARD (xsignbit) MAPPER_FORWARD (xtoascii) MAPPER_FORWARD (xtolower) MAPPER_FORWARD (xtoupper)
--- a/libinterp/octave.cc +++ b/libinterp/octave.cc @@ -43,15 +43,16 @@ #include "file-stat.h" #include "lo-error.h" #include "oct-env.h" -#include "pathsearch.h" #include "str-vec.h" -#include <defaults.h> +#include "builtins.h" +#include "defaults.h" #include "Cell.h" #include "defun.h" #include "display.h" #include "error.h" #include "file-io.h" +#include "help.h" #include "input.h" #include "lex.h" #include "load-path.h" @@ -113,10 +114,6 @@ // (--quiet; --silent; -q) static bool inhibit_startup_message = false; -// TRUE means we turn on compatibility options. -// (--traditional) -static bool traditional = false; - // If TRUE, print verbose info in some cases. // (--verbose; -V) static bool verbose_flag = false; @@ -141,15 +138,6 @@ // (--path; -p) static std::list<std::string> command_line_path; -// Flags used to determine what commands should be echoed when they are -// parsed and executed. -// (--echo-commands; -x) -static int echo_executing_commands = 0; - -// The file used for the doc string cache. -// (--doc-cache-file) -static std::string doc_cache_file; - // The value for "EXEC_PATH" specified on the command line. // (--exec-path) static std::string exec_path; @@ -158,34 +146,23 @@ // (--image-path) static std::string image_path; -// The value for "info_file" specified on the command line. -// (--info-file) -static std::string info_file; - -// The value for "info_program" specified on the command line. -// (--info-program) -static std::string info_program; - // If TRUE, ignore the window system even if it is available. // (--no-window-system) static bool no_window_system = false; -// The value for "texi_macros_file" specified on the command line. -// (--texi-macros-file) -static std::string texi_macros_file; - // Usage message static const char *usage_string = "octave [-HVdfhiqvx] [--debug] [--echo-commands] [--eval CODE]\n\ [--exec-path path] [--force-gui] [--help] [--image-path path]\n\ [--info-file file] [--info-program prog] [--interactive]\n\ - [--line-editing] [--no-gui] [--no-history] [--no-init-file]\n\ - [--no-init-path] [--no-line-editing] [--no-site-file]\n\ - [--no-window-system] [-p path] [--path path] [--silent]\n\ - [--traditional] [--verbose] [--version] [file]"; + [--jit-debugging] [--line-editing] [--no-gui] [--no-history]\n\ + [--no-init-file] [--no-init-path] [--no-jit-compiler]\n\ + [--no-line-editing] [--no-site-file] [--no-window-system]\n\ + [-p path] [--path path] [--silent] [--traditional]\n\ + [--verbose] [--version] [file]"; // This is here so that it's more likely that the usage message and -// the real set of options will agree. Note: the `+' must come first +// the real set of options will agree. Note: the '+' must come first // to prevent getopt from permuting arguments! static const char *short_opts = "+HVdfhip:qvx"; @@ -197,56 +174,61 @@ // Long options. See the comments in getopt.h for the meanings of the // fields in this structure. -#define DOC_CACHE_FILE_OPTION 1 -#define EVAL_OPTION 2 -#define EXEC_PATH_OPTION 3 -#define FORCE_GUI_OPTION 4 -#define IMAGE_PATH_OPTION 5 -#define INFO_FILE_OPTION 6 -#define INFO_PROG_OPTION 7 -#define LINE_EDITING_OPTION 8 -#define NO_GUI_OPTION 9 -#define NO_INIT_FILE_OPTION 10 -#define NO_INIT_PATH_OPTION 11 -#define NO_LINE_EDITING_OPTION 12 -#define NO_SITE_FILE_OPTION 13 -#define NO_WINDOW_SYSTEM_OPTION 14 -#define PERSIST_OPTION 15 -#define TEXI_MACROS_FILE_OPTION 16 -#define TRADITIONAL_OPTION 17 -struct option long_opts[] = - { - { "braindead", no_argument, 0, TRADITIONAL_OPTION }, - { "debug", no_argument, 0, 'd' }, - { "doc-cache-file", required_argument, 0, DOC_CACHE_FILE_OPTION }, - { "echo-commands", no_argument, 0, 'x' }, - { "eval", required_argument, 0, EVAL_OPTION }, - { "exec-path", required_argument, 0, EXEC_PATH_OPTION }, - { "force-gui", no_argument, 0, FORCE_GUI_OPTION }, - { "help", no_argument, 0, 'h' }, - { "image-path", required_argument, 0, IMAGE_PATH_OPTION }, - { "info-file", required_argument, 0, INFO_FILE_OPTION }, - { "info-program", required_argument, 0, INFO_PROG_OPTION }, - { "interactive", no_argument, 0, 'i' }, - { "line-editing", no_argument, 0, LINE_EDITING_OPTION }, - { "no-gui", no_argument, 0, NO_GUI_OPTION }, - { "no-history", no_argument, 0, 'H' }, - { "no-init-file", no_argument, 0, NO_INIT_FILE_OPTION }, - { "no-init-path", no_argument, 0, NO_INIT_PATH_OPTION }, - { "no-line-editing", no_argument, 0, NO_LINE_EDITING_OPTION }, - { "no-site-file", no_argument, 0, NO_SITE_FILE_OPTION }, - { "no-window-system", no_argument, 0, NO_WINDOW_SYSTEM_OPTION }, - { "norc", no_argument, 0, 'f' }, - { "path", required_argument, 0, 'p' }, - { "persist", no_argument, 0, PERSIST_OPTION }, - { "quiet", no_argument, 0, 'q' }, - { "silent", no_argument, 0, 'q' }, - { "texi-macros-file", required_argument, 0, TEXI_MACROS_FILE_OPTION }, - { "traditional", no_argument, 0, TRADITIONAL_OPTION }, - { "verbose", no_argument, 0, 'V' }, - { "version", no_argument, 0, 'v' }, - { 0, 0, 0, 0 } - }; +#define BUILT_IN_DOCSTRINGS_FILE_OPTION 1 +#define DOC_CACHE_FILE_OPTION 2 +#define EVAL_OPTION 3 +#define EXEC_PATH_OPTION 4 +#define FORCE_GUI_OPTION 5 +#define IMAGE_PATH_OPTION 6 +#define INFO_FILE_OPTION 7 +#define INFO_PROG_OPTION 8 +#define JIT_DEBUGGING_OPTION 9 +#define LINE_EDITING_OPTION 10 +#define NO_GUI_OPTION 11 +#define NO_INIT_FILE_OPTION 12 +#define NO_INIT_PATH_OPTION 13 +#define NO_JIT_COMPILER_OPTION 14 +#define NO_LINE_EDITING_OPTION 15 +#define NO_SITE_FILE_OPTION 16 +#define NO_WINDOW_SYSTEM_OPTION 17 +#define PERSIST_OPTION 18 +#define TEXI_MACROS_FILE_OPTION 19 +#define TRADITIONAL_OPTION 20 +struct option long_opts[] = { + { "braindead", no_argument, 0, TRADITIONAL_OPTION }, + { "built-in-docstrings-file", required_argument, 0, BUILT_IN_DOCSTRINGS_FILE_OPTION }, + { "debug", no_argument, 0, 'd' }, + { "doc-cache-file", required_argument, 0, DOC_CACHE_FILE_OPTION }, + { "echo-commands", no_argument, 0, 'x' }, + { "eval", required_argument, 0, EVAL_OPTION }, + { "exec-path", required_argument, 0, EXEC_PATH_OPTION }, + { "force-gui", no_argument, 0, FORCE_GUI_OPTION }, + { "help", no_argument, 0, 'h' }, + { "image-path", required_argument, 0, IMAGE_PATH_OPTION }, + { "info-file", required_argument, 0, INFO_FILE_OPTION }, + { "info-program", required_argument, 0, INFO_PROG_OPTION }, + { "interactive", no_argument, 0, 'i' }, + { "jit-debugging", no_argument, 0, JIT_DEBUGGING_OPTION }, + { "line-editing", no_argument, 0, LINE_EDITING_OPTION }, + { "no-gui", no_argument, 0, NO_GUI_OPTION }, + { "no-history", no_argument, 0, 'H' }, + { "no-init-file", no_argument, 0, NO_INIT_FILE_OPTION }, + { "no-init-path", no_argument, 0, NO_INIT_PATH_OPTION }, + { "no-jit-compiler", no_argument, 0, NO_JIT_COMPILER_OPTION }, + { "no-line-editing", no_argument, 0, NO_LINE_EDITING_OPTION }, + { "no-site-file", no_argument, 0, NO_SITE_FILE_OPTION }, + { "no-window-system", no_argument, 0, NO_WINDOW_SYSTEM_OPTION }, + { "norc", no_argument, 0, 'f' }, + { "path", required_argument, 0, 'p' }, + { "persist", no_argument, 0, PERSIST_OPTION }, + { "quiet", no_argument, 0, 'q' }, + { "silent", no_argument, 0, 'q' }, + { "texi-macros-file", required_argument, 0, TEXI_MACROS_FILE_OPTION }, + { "traditional", no_argument, 0, TRADITIONAL_OPTION }, + { "verbose", no_argument, 0, 'V' }, + { "version", no_argument, 0, 'v' }, + { 0, 0, 0, 0 } +}; // Store the command-line options for later use. @@ -270,24 +252,6 @@ } } -static void -initialize_pathsearch (void) -{ - // This may seem odd, but doing it this way means that we don't have - // to modify the kpathsea library... - - std::string odb = octave_env::getenv ("OCTAVE_DB_PATH"); - - // For backward compatibility. - - if (odb.empty ()) - odb = octave_env::getenv ("OCTAVE_DB_DIR"); - - if (odb.empty ()) - odb = Vdata_dir + file_ops::dir_sep_str () + "octave:" - + Vlibexec_dir + file_ops::dir_sep_str () + "octave"; -} - DEFUN (__version_info__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {retval =} __version_info__ (@var{name}, @var{version}, @var{release}, @var{date})\n\ @@ -380,14 +344,6 @@ recover_from_exception (); gripe_safe_source_exception (file_name, "unhandled execution exception"); } - catch (std::bad_alloc) - { - recover_from_exception (); - error_state = -2; - gripe_safe_source_exception - (file_name, - "memory exhausted or requested size too large for range of Octave's index type"); - } } // Initialize by reading startup files. @@ -508,12 +464,6 @@ std::cerr << "error: unhandled execution exception -- eval failed" << std::endl; } - catch (std::bad_alloc) - { - error_state = -2; - std::cerr << "error: memory exhausted or requested size too large for range of Octave's index type -- eval failed" - << std::endl; - } return parse_status; } @@ -590,11 +540,13 @@ --info-file FILE Use top-level info file FILE.\n\ --info-program PROGRAM Use PROGRAM for reading info files.\n\ --interactive, -i Force interactive behavior.\n\ + --jit-debug Enable JIT compiler debugging/tracing.\n\ --line-editing Force readline use for command-line editing.\n\ --no-gui Disable the graphical user interface.\n\ --no-history, -H Don't save commands to the history list\n\ --no-init-file Don't read the ~/.octaverc or .octaverc files.\n\ --no-init-path Don't initialize function search path.\n\ + --no-jit-compiler Disable the JIT compiler.\n\ --no-line-editing Don't use readline for command-line editing.\n\ --no-site-file Don't read the site-wide octaverc file.\n\ --no-window-system Disable window system, including graphics.\n\ @@ -673,19 +625,19 @@ { persist = true; - bind_internal_variable ("PS1", ">> "); - bind_internal_variable ("PS2", ""); - bind_internal_variable ("allow_noninteger_range_as_index", true); - bind_internal_variable ("beep_on_error", true); - bind_internal_variable ("confirm_recursive_rmdir", false); - bind_internal_variable ("crash_dumps_octave_core", false); - bind_internal_variable ("default_save_options", "-mat-binary"); - bind_internal_variable ("do_braindead_shortcircuit_evaluation", true); - bind_internal_variable ("fixed_point_format", true); - bind_internal_variable ("history_timestamp_format_string", - "%%-- %D %I:%M %p --%%"); - bind_internal_variable ("page_screen_output", false); - bind_internal_variable ("print_empty_dimensions", false); + FPS1 (octave_value (">> ")); + FPS2 (octave_value ("")); + FPS4 (octave_value ("")); + Fallow_noninteger_range_as_index (octave_value (true)); + Fbeep_on_error (octave_value (true)); + Fconfirm_recursive_rmdir (octave_value (false)); + Fcrash_dumps_octave_core (octave_value (false)); + Fdefault_save_options (octave_value ("-mat-binary")); + Fdo_braindead_shortcircuit_evaluation (octave_value (true)); + Ffixed_point_format (octave_value (true)); + Fhistory_timestamp_format_string (octave_value ("%%-- %D %I:%M %p --%%")); + Fpage_screen_output (octave_value (false)); + Fprint_empty_dimensions (octave_value (false)); disable_warning ("Octave:abbreviated-property-match"); disable_warning ("Octave:fopen-file-in-path"); @@ -702,6 +654,8 @@ { octave_process_command_line (argc, argv); + install_defaults (); + octave_initialize_interpreter (argc, argv, embedded); return octave_execute_interpreter (); @@ -732,6 +686,7 @@ break; case 'H': + Fsaving_history (octave_value (false)); read_history_file = false; break; @@ -767,17 +722,24 @@ break; case 'x': - echo_executing_commands - = (ECHO_SCRIPTS | ECHO_FUNCTIONS | ECHO_CMD_LINE); + { + int val = ECHO_SCRIPTS | ECHO_FUNCTIONS | ECHO_CMD_LINE; + Fecho_executing_commands (octave_value (val)); + } break; case 'v': print_version_and_exit (); break; + case BUILT_IN_DOCSTRINGS_FILE_OPTION: + if (optarg) + Fbuilt_in_docstrings_file (octave_value (optarg)); + break; + case DOC_CACHE_FILE_OPTION: if (optarg) - doc_cache_file = optarg; + Fdoc_cache_file (octave_value (optarg)); break; case EVAL_OPTION: @@ -806,28 +768,36 @@ case INFO_FILE_OPTION: if (optarg) - info_file = optarg; + Finfo_file (octave_value (optarg)); break; case INFO_PROG_OPTION: if (optarg) - info_program = optarg; + Finfo_program (octave_value (optarg)); + break; + + case JIT_DEBUGGING_OPTION: + Fenable_jit_debugging (octave_value (true)); break; case LINE_EDITING_OPTION: forced_line_editing = true; break; + case NO_GUI_OPTION: + no_gui_option = true; + break; + case NO_INIT_FILE_OPTION: read_init_files = false; break; - case NO_GUI_OPTION: - no_gui_option = true; + case NO_INIT_PATH_OPTION: + set_initial_path = false; break; - case NO_INIT_PATH_OPTION: - set_initial_path = false; + case NO_JIT_COMPILER_OPTION: + Fenable_jit_compiler (octave_value (false)); break; case NO_LINE_EDITING_OPTION: @@ -848,11 +818,11 @@ case TEXI_MACROS_FILE_OPTION: if (optarg) - texi_macros_file = optarg; + Ftexi_macros_file (octave_value (optarg)); break; case TRADITIONAL_OPTION: - traditional = true; + maximum_braindamage (); break; default: @@ -887,13 +857,6 @@ octave_thread::init (); - // The order of these calls is important. The call to - // install_defaults must come before install_builtins because - // default variable values must be available for the variables to be - // installed, and the call to install_builtins must come before the - // options are processed because some command line options override - // defaults by calling bind_internal_variable. - init_signals (); sysdep_init (); @@ -912,10 +875,6 @@ initialize_default_warning_state (); - install_defaults (); - - initialize_pathsearch (); - if (! embedded) install_signal_handlers (); else @@ -929,38 +888,19 @@ install_builtins (); - if (! read_history_file) - bind_internal_variable ("saving_history", false); - for (std::list<std::string>::const_iterator it = command_line_path.begin (); it != command_line_path.end (); it++) load_path::set_command_line_path (*it); - if (echo_executing_commands) - bind_internal_variable ("echo_executing_commands", - echo_executing_commands); - - if (! doc_cache_file.empty ()) - bind_internal_variable ("doc_cache_file", doc_cache_file); - if (! exec_path.empty ()) set_exec_path (exec_path); if (! image_path.empty ()) - set_exec_path (image_path); - - if (! info_file.empty ()) - bind_internal_variable ("info_file", info_file); - - if (! info_program.empty ()) - bind_internal_variable ("info_program", info_program); + set_image_path (image_path); if (no_window_system) display_info::no_window_system (); - if (! texi_macros_file.empty ()) - bind_internal_variable ("texi_macros_file", texi_macros_file); - // Make sure we clean up when we exit. Also allow users to register // functions. If we don't have atexit or on_exit, we're going to // leave some junk files around if we exit abnormally. @@ -990,9 +930,6 @@ if (line_editing) initialize_command_input (); - if (traditional) - maximum_braindamage (); - octave_interpreter_ready = true; initialize_version_info (); @@ -1070,7 +1007,7 @@ // FIXME -- is this the right thing to do? - bind_internal_variable ("echo_executing_commands", ECHO_CMD_LINE); + Fecho_executing_commands (octave_value (ECHO_CMD_LINE)); } if (octave_embedded) @@ -1100,7 +1037,7 @@ int octave_starting_gui (void) { - if (! display_info::display_available ()) + if (no_window_system || ! display_info::display_available ()) return false; if (force_gui_option)
--- a/libinterp/operators/module.mk +++ b/libinterp/operators/module.mk @@ -130,7 +130,7 @@ operators/op-ui8-ui8.cc ## These look like included header files to Autotools build process -OPERATOR_INCLUDES = \ +OPERATORS_INC = \ operators/op-dm-template.cc \ operators/op-dms-template.cc \ operators/op-int.h \
--- a/libinterp/parse-tree/lex.ll +++ b/libinterp/parse-tree/lex.ll @@ -109,7 +109,7 @@ // Try to avoid crashing out completely on fatal scanner errors. // The call to yy_fatal_error should never happen, but it avoids a -// `static function defined but not used' warning from gcc. +// 'static function defined but not used' warning from gcc. #ifdef YY_FATAL_ERROR #undef YY_FATAL_ERROR @@ -439,7 +439,7 @@ %{ // For this and the next two rules, we're looking at ']', and we -// need to know if the next token is `=' or `=='. +// need to know if the next token is '=' or '=='. // // It would have been so much easier if the delimiters were simply // different for the expression on the left hand side of the equals @@ -681,7 +681,7 @@ } %{ -// Real numbers. Don't grab the `.' part of a dot operator as part of +// Real numbers. Don't grab the '.' part of a dot operator as part of // the constant. %} @@ -730,7 +730,7 @@ if ((reading_fcn_file || reading_script_file || reading_classdef_file) && ! curr_fcn_file_name.empty ()) - warning ("near line %d of file `%s.m'", + warning ("near line %d of file '%s.m'", input_line_number, curr_fcn_file_name.c_str ()); } @@ -1078,7 +1078,7 @@ { current_input_column++; - error ("invalid character `%s' (ASCII %d) near line %d, column %d", + error ("invalid character '%s' (ASCII %d) near line %d, column %d", undo_string_escape (static_cast<char> (c)), c, input_line_number, current_input_column); @@ -1515,12 +1515,12 @@ || reading_classdef_file) && ! curr_fcn_file_full_name.empty ()) warning_with_id ("Octave:deprecated-keyword", - "the `static' keyword is obsolete and will be removed from a future version of Octave; please use `persistent' instead; near line %d of file `%s'", + "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d of file '%s'", input_line_number, curr_fcn_file_full_name.c_str ()); else warning_with_id ("Octave:deprecated-keyword", - "the `static' keyword is obsolete and will be removed from a future version of Octave; please use `persistent' instead; near line %d", + "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d", input_line_number); // fall through ... @@ -2557,7 +2557,7 @@ return false; } -// We have seen a `.' and need to see if it is the start of a +// We have seen a '.' and need to see if it is the start of a // continuation. If so, this eats it, up to and including the new // line character. @@ -3353,7 +3353,7 @@ // If we are looking at a text style function, set up to gobble its // arguments. // - // If the following token is `=', or if we are parsing a function + // If the following token is '=', or if we are parsing a function // return list or function parameter list, or if we are looking at // something like [ab,cd] = foo (), force the symbol to be inserted // as a variable in the current symbol table. @@ -3579,11 +3579,11 @@ if (nm.empty ()) warning_with_id ("Octave:separator-insert", - "potential auto-insertion of `%c' near line %d", + "potential auto-insertion of '%c' near line %d", sep, input_line_number); else warning_with_id ("Octave:separator-insert", - "potential auto-insertion of `%c' near line %d of file %s", + "potential auto-insertion of '%c' near line %d of file %s", sep, input_line_number, nm.c_str ()); }
--- a/libinterp/parse-tree/module.mk +++ b/libinterp/parse-tree/module.mk @@ -2,7 +2,7 @@ parse-tree/module.mk \ parse-tree/octave.gperf -PARSER_INCLUDES = \ +PARSER_INC = \ parse-tree/lex.h \ parse-tree/parse.h \ parse-tree/parse-private.h @@ -11,10 +11,14 @@ parse-tree/lex.ll \ parse-tree/oct-parse.yy -lex.lo lex.o oct-parse.lo oct-parse.o: \ - AM_CXXFLAGS := $(filter-out -Wold-style-cast, $(AM_CXXFLAGS)) +## FIXME: Automake does not support per-object rules. +## These rules could be emulated by creating a new convenience +## library and using per-library rules. Or we can just live +## with the extra warnings about old-sytle-casts. (09/18/2012) +#lex.lo lex.o oct-parse.lo oct-parse.o: \ +# AM_CXXFLAGS := $(filter-out -Wold-style-cast, $(AM_CXXFLAGS)) -PT_INCLUDES = \ +PARSE_TREE_INC = \ parse-tree/pt-all.h \ parse-tree/pt-arg-list.h \ parse-tree/pt-assign.h \ @@ -46,7 +50,7 @@ parse-tree/pt-walk.h \ parse-tree/pt.h \ parse-tree/token.h \ - $(PARSER_INCLUDES) + $(PARSER_INC) PARSE_TREE_SRC = \ parse-tree/pt-arg-list.cc \ @@ -95,3 +99,4 @@ noinst_LTLIBRARIES += parse-tree/libparse-tree.la parse_tree_libparse_tree_la_SOURCES = $(PARSE_TREE_SRC) +parse_tree_libparse_tree_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS)
--- a/libinterp/parse-tree/oct-parse.yy +++ b/libinterp/parse-tree/oct-parse.yy @@ -988,7 +988,7 @@ { $$ = make_boolean_op (EXPR_OR_OR, $1, $2, $3); } ; -// Arrange for the lexer to return CLOSE_BRACE for `]' by looking ahead +// Arrange for the lexer to return CLOSE_BRACE for ']' by looking ahead // one token for an assignment op. assign_lhs : simple_expr @@ -1300,7 +1300,7 @@ ; // =========================================== -// Some `subroutines' for function definitions +// Some 'subroutines' for function definitions // =========================================== push_fcn_symtab : // empty @@ -1875,7 +1875,7 @@ end_error (const char *type, token::end_tok_type ettype, int l, int c) { static const char *fmt - = "`%s' command matched by `%s' near line %d column %d"; + = "'%s' command matched by '%s' near line %d column %d"; switch (ettype) { @@ -2006,7 +2006,7 @@ else warning_with_id ("Octave:assign-as-truth-value", - "suggest parenthesis around assignment used as truth value near line %d, column %d in file `%s'", + "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'", expr->line (), expr->column (), curr_fcn_file_full_name.c_str ()); } } @@ -2024,7 +2024,7 @@ else warning_with_id ("Octave:variable-switch-label", - "variable switch label near line %d, column %d in file `%s'", + "variable switch label near line %d, column %d in file '%s'", expr->line (), expr->column (), curr_fcn_file_full_name.c_str ()); } } @@ -2988,7 +2988,7 @@ { warning_with_id ("Octave:function-name-clash", - "function name `%s' does not agree with function file name `%s'", + "function name '%s' does not agree with function file name '%s'", id_name.c_str (), curr_fcn_file_full_name.c_str ()); id_name = nm; @@ -3032,13 +3032,13 @@ if (fs && fs.is_newer (now)) warning_with_id ("Octave:future-time-stamp", - "time stamp for `%s' is in the future", nm.c_str ()); + "time stamp for '%s' is in the future", nm.c_str ()); } else if (! (input_from_tmp_history_file || input_from_startup_file) && reading_script_file && curr_fcn_file_name == id_name) { - warning ("function `%s' defined within script file `%s'", + warning ("function '%s' defined within script file '%s'", id_name.c_str (), curr_fcn_file_full_name.c_str ()); } @@ -3258,7 +3258,7 @@ else { if (reading_script_file) - warning ("ignoring persistent declaration near line %d of file `%s'", + warning ("ignoring persistent declaration near line %d of file '%s'", l, curr_fcn_file_full_name.c_str ()); else warning ("ignoring persistent declaration near line %d", l); @@ -3343,7 +3343,7 @@ if (tmp->is_expression ()) warning_with_id ("Octave:missing-semicolon", - "missing semicolon near line %d, column %d in file `%s'", + "missing semicolon near line %d, column %d in file '%s'", tmp->line (), tmp->column (), curr_fcn_file_full_name.c_str ()); } } @@ -3914,9 +3914,9 @@ } } else if (require_file) - error ("no such file, `%s'", ff.c_str ()); + error ("no such file, '%s'", ff.c_str ()); else if (! warn_for.empty ()) - error ("%s: unable to open file `%s'", warn_for.c_str (), ff.c_str ()); + error ("%s: unable to open file '%s'", warn_for.c_str (), ff.c_str ()); return fcn_ptr; } @@ -4202,7 +4202,7 @@ } if (! found) warning_with_id ("Octave:autoload-relative-file-name", - "autoload: `%s' is not an absolute file name", + "autoload: '%s' is not an absolute file name", nm.c_str ()); } autoload_map[argv[1]] = nm; @@ -4318,7 +4318,7 @@ } } else - error ("source: error sourcing file `%s'", + error ("source: error sourcing file '%s'", file_full_name.c_str ()); } } @@ -4447,7 +4447,7 @@ { maybe_missing_function_hook (name); if (! error_state) - error ("feval: function `%s' not found", name.c_str ()); + error ("feval: function '%s' not found", name.c_str ()); } return retval; @@ -4587,7 +4587,7 @@ retval = feval (fcn.function_value (), args.splice (0, 1), nargout); else - error ("builtin: lookup for symbol `%s' failed", name.c_str ()); + error ("builtin: lookup for symbol '%s' failed", name.c_str ()); } else error ("builtin: function name (F) must be a string"); @@ -4666,7 +4666,7 @@ // Unmark forced variables. // Restore previous value of global_command. - frame.run_top (2); + frame.run (2); if (parse_status == 0) {
--- a/libinterp/parse-tree/pt-binop.cc +++ b/libinterp/parse-tree/pt-binop.cc @@ -46,7 +46,7 @@ octave_value_list retval; if (nargout > 1) - error ("binary operator `%s': invalid number of output arguments", + error ("binary operator '%s': invalid number of output arguments", oper () . c_str ()); else retval = rvalue1 (nargout); @@ -176,7 +176,7 @@ octave_value_list retval; if (nargout > 1) - error ("binary operator `%s': invalid number of output arguments", + error ("binary operator '%s': invalid number of output arguments", oper () . c_str ()); else retval = rvalue1 (nargout);
--- a/libinterp/parse-tree/pt-decl.h +++ b/libinterp/parse-tree/pt-decl.h @@ -84,6 +84,8 @@ tree_identifier *ident (void) { return id; } + std::string name (void) { return id ? id->name () : ""; } + tree_expression *expression (void) { return expr; } tree_decl_elt *dup (symbol_table::scope_id scope,
--- a/libinterp/parse-tree/pt-eval.cc +++ b/libinterp/parse-tree/pt-eval.cc @@ -44,11 +44,8 @@ #include "symtab.h" #include "unwind-prot.h" -#if HAVE_LLVM //FIXME: This should be part of tree_evaluator #include "pt-jit.h" -static tree_jit jiter; -#endif static tree_evaluator std_evaluator; @@ -271,7 +268,7 @@ { octave_quit (); - // Maybe handle `continue N' someday... + // Maybe handle 'continue N' someday... if (tree_continue_command::continuing) tree_continue_command::continuing--; @@ -310,7 +307,7 @@ octave_value rhs = expr->rvalue1 (); #if HAVE_LLVM - if (jiter.execute (cmd, rhs)) + if (Venable_jit_compiler && tree_jit::execute (cmd, rhs)) return; #endif @@ -491,7 +488,7 @@ } } else - error ("in statement `for [X, Y] = VAL', VAL must be a structure"); + error ("in statement 'for [X, Y] = VAL', VAL must be a structure"); } void @@ -763,6 +760,19 @@ { gripe_library_execution_error (); } + catch (std::bad_alloc) + { + // FIXME -- We want to use error_with_id here so that we set + // the error state, give users control over this error + // message, and so that we set the error_state appropriately + // so we'll get stack trace info when appropriate. But + // error_with_id will require some memory allocations. Is + // there anything we can do to make those more likely to + // succeed? + + error_with_id ("Octave:bad-alloc", + "out of memory or dimension too large for Octave's index type"); + } } } @@ -903,7 +913,6 @@ if (try_code) { try_code->accept (*this); - // FIXME: should std::bad_alloc be handled here? } if (error_state) @@ -987,11 +996,11 @@ if (tree_break_command::breaking || tree_return_command::returning) { - frame.discard_top (2); + frame.discard (2); } else { - frame.run_top (2); + frame.run (2); } // We don't want to ignore errors that occur in the cleanup code, so @@ -999,9 +1008,9 @@ // Otherwise, set it back to what it was before. if (error_state) - frame.discard_top (2); + frame.discard (2); else - frame.run_top (2); + frame.run (2); frame.run (); } @@ -1041,7 +1050,7 @@ return; #if HAVE_LLVM - if (jiter.execute (cmd)) + if (Venable_jit_compiler && tree_jit::execute (cmd)) return; #endif
--- a/libinterp/parse-tree/pt-id.cc +++ b/libinterp/parse-tree/pt-id.cc @@ -50,10 +50,10 @@ if (l == -1 && c == -1) ::error_with_id ("Octave:undefined-function", - "`%s' undefined", name ().c_str ()); + "'%s' undefined", name ().c_str ()); else ::error_with_id ("Octave:undefined-function", - "`%s' undefined near line %d column %d", + "'%s' undefined near line %d column %d", name ().c_str (), l, c); } @@ -74,7 +74,7 @@ // // If this identifier refers to a function, we need to know // whether it is indexed so that we can do the same thing - // for `f' and `f()'. If the index is present, return the + // for 'f' and 'f()'. If the index is present, return the // function object and let tree_index_expression::rvalue // handle indexing. Otherwise, arrange to call the function // here, so that we don't return the function definition as @@ -94,6 +94,8 @@ retval = val; } } + else if (sym->is_added_static ()) + static_workspace_error (); else eval_undefined_error (); @@ -116,6 +118,9 @@ octave_lvalue tree_identifier::lvalue (void) { + if (sym->is_added_static ()) + static_workspace_error (); + return octave_lvalue (&(sym->varref ())); }
--- a/libinterp/parse-tree/pt-id.h +++ b/libinterp/parse-tree/pt-id.h @@ -110,6 +110,12 @@ void eval_undefined_error (void); + void static_workspace_error (void) + { + ::error ("can not add variable \"%s\" to a static workspace", + name ().c_str ()); + } + tree_identifier *dup (symbol_table::scope_id scope, symbol_table::context_id context) const;
--- a/libinterp/parse-tree/pt-idx.cc +++ b/libinterp/parse-tree/pt-idx.cc @@ -220,7 +220,7 @@ fn = t.string_value (); if (! valid_identifier (fn)) - ::error ("invalid structure field name `%s'", fn.c_str ()); + ::error ("invalid structure field name '%s'", fn.c_str ()); } } else
--- a/libinterp/parse-tree/pt-misc.cc +++ b/libinterp/parse-tree/pt-misc.cc @@ -83,7 +83,7 @@ else if (dict.find (name) != dict.end ()) { retval = false; - error ("`%s' appears more than once in parameter list", + error ("'%s' appears more than once in parameter list", name.c_str ()); break; }
--- a/libinterp/parse-tree/pt-unop.cc +++ b/libinterp/parse-tree/pt-unop.cc @@ -49,7 +49,7 @@ octave_value_list retval; if (nargout > 1) - error ("prefix operator `%s': invalid number of output arguments", + error ("prefix operator '%s': invalid number of output arguments", oper () . c_str ()); else retval = rvalue1 (nargout); @@ -136,7 +136,7 @@ octave_value_list retval; if (nargout > 1) - error ("postfix operator `%s': invalid number of output arguments", + error ("postfix operator '%s': invalid number of output arguments", oper () . c_str ()); else retval = rvalue1 (nargout);
--- a/libinterp/version.in.h +++ b/libinterp/version.in.h @@ -58,7 +58,7 @@ #define OCTAVE_CONTRIB_STATEMENT \ "Please contribute if you find this software useful.\n\ -For more information, visit http://www.octave.org/help-wanted.html" +For more information, visit http://www.octave.org/get-involved.html" #define OCTAVE_BUGS_STATEMENT \ "Read http://www.octave.org/bugs.html to learn how to submit bug reports." @@ -87,6 +87,6 @@ #define OCTAVE_STARTUP_MESSAGE \ X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS \ - (" For details, type `warranty'.") "\n\n" \ - "For information about changes from previous versions, type `news'." + (" For details, type 'warranty'.") "\n\n" \ + "For information about changes from previous versions, type 'news'." #endif
--- a/liboctave/Makefile.am +++ b/liboctave/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's liboctave directory +# Makefile for Octave's liboctave directory # # Copyright (C) 1993-2012 John W. Eaton # @@ -20,265 +20,34 @@ include $(top_srcdir)/build-aux/common.mk +AUTOMAKE_OPTIONS = subdir-objects + +## Run cruft dir with stand-alone Makefile. +## Eventually this will use module.mk syntax. +SUBDIRS = cruft + ## Search local directories before those specified by the user. AM_CPPFLAGS = \ - -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu \ - -I$(top_srcdir)/libcruft/misc - -EXTRA_DIST = \ - config-ops.sh \ - mk-ops.awk \ - mx-op-inc.mk \ - mx-op-src.mk \ - mx-ops \ - smx-op-inc.mk \ - smx-op-src.mk \ - sparse-mk-ops.awk \ - sparse-mx-ops \ - vx-op-inc.mk \ - vx-op-src.mk \ - vx-ops \ - $(OPT_IN) + -I$(srcdir)/array \ + -I$(srcdir)/cruft/misc \ + -Inumeric -I$(srcdir)/numeric \ + -Ioperators -I$(srcdir)/operators \ + -I$(srcdir)/system \ + -I$(srcdir)/util \ + -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu -MATRIX_INC = \ - Array-util.h \ - Array.h \ - Array2.h \ - Array3.h \ - ArrayN.h \ - CColVector.h \ - CDiagMatrix.h \ - CMatrix.h \ - CNDArray.h \ - CRowVector.h \ - CSparse.h \ - CmplxAEPBAL.h \ - CmplxCHOL.h \ - CmplxGEPBAL.h \ - CmplxHESS.h \ - CmplxLU.h \ - CmplxQR.h \ - CmplxQRP.h \ - CmplxSCHUR.h \ - CmplxSVD.h \ - DET.h \ - DiagArray2.h \ - EIG.h \ - MArray-decl.h \ - MArray-defs.h \ - MArray.h \ - MArray2.h \ - MArrayN.h \ - MDiagArray2.h \ - MSparse-defs.h \ - MSparse.h \ - Matrix.h \ - MatrixType.h \ - PermMatrix.h \ - Sparse-diag-op-defs.h \ - Sparse-op-defs.h \ - Sparse-perm-op-defs.h \ - Sparse.h \ - SparseCmplxCHOL.h \ - SparseCmplxLU.h \ - SparseCmplxQR.h \ - SparseQR.h \ - SparsedbleCHOL.h \ - SparsedbleLU.h \ - base-aepbal.h \ - base-lu.h \ - base-qr.h \ - boolMatrix.h \ - boolNDArray.h \ - boolSparse.h \ - bsxfun-decl.h \ - chMatrix.h \ - chNDArray.h \ - dColVector.h \ - dDiagMatrix.h \ - dMatrix.h \ - dNDArray.h \ - dRowVector.h \ - dSparse.h \ - dbleAEPBAL.h \ - dbleCHOL.h \ - dbleGEPBAL.h \ - dbleHESS.h \ - dbleLU.h \ - dbleQR.h \ - dbleQRP.h \ - dbleSCHUR.h \ - dbleSVD.h \ - dim-vector.h \ - fCColVector.h \ - fCDiagMatrix.h \ - fCMatrix.h \ - fCNDArray.h \ - fCRowVector.h \ - fCmplxAEPBAL.h \ - fCmplxCHOL.h \ - fCmplxGEPBAL.h \ - fCmplxHESS.h \ - fCmplxLU.h \ - fCmplxQR.h \ - fCmplxQRP.h \ - fCmplxSCHUR.h \ - fCmplxSVD.h \ - fColVector.h \ - fDiagMatrix.h \ - fEIG.h \ - fMatrix.h \ - fNDArray.h \ - fRowVector.h \ - floatAEPBAL.h \ - floatCHOL.h \ - floatGEPBAL.h \ - floatHESS.h \ - floatLU.h \ - floatQR.h \ - floatQRP.h \ - floatSCHUR.h \ - floatSVD.h \ - int16NDArray.h \ - int32NDArray.h \ - int64NDArray.h \ - int8NDArray.h \ - intNDArray.h \ - mx-base.h \ - mx-defs.h \ - mx-ext.h \ - mx-op-decl.h \ - mx-op-defs.h \ - sparse-base-chol.h \ - sparse-base-lu.h \ - uint16NDArray.h \ - uint32NDArray.h \ - uint64NDArray.h \ - uint8NDArray.h +AM_CFLAGS += $(WARN_CFLAGS) + +AM_CXXFLAGS += $(WARN_CXXFLAGS) -OPT_IN = \ - DASPK-opts.in \ - DASRT-opts.in \ - DASSL-opts.in \ - LSODE-opts.in \ - Quad-opts.in - -OPT_INC = \ - DASPK-opts.h \ - DASRT-opts.h \ - DASSL-opts.h \ - LSODE-opts.h \ - Quad-opts.h +octlib_LTLIBRARIES = liboctave.la -INCS = \ - CollocWt.h \ - DAE.h \ - DAEFunc.h \ - DAERT.h \ - DAERTFunc.h \ - DASPK.h \ - DASRT.h \ - DASSL.h \ - LSODE.h \ - ODE.h \ - ODEFunc.h \ - ODES.h \ - ODESFunc.h \ - Quad.h \ - Range.h \ - base-dae.h \ - base-de.h \ - base-list.h \ - base-min.h \ - bsxfun.h \ - byte-swap.h \ - caseless-str.h \ - cmd-edit.h \ - cmd-hist.h \ - data-conv.h \ - dir-ops.h \ - file-ops.h \ - file-stat.h \ - functor.h \ - glob-match.h \ - idx-vector.h \ - lo-array-gripes.h \ - lo-cutils.h \ - lo-ieee.h \ - lo-macros.h \ - lo-mappers.h \ - lo-math.h \ - lo-specfun.h \ - lo-sysdep.h \ - lo-traits.h \ - lo-utils.h \ - mach-info.h \ - oct-alloc.h \ - oct-binmap.h \ - oct-cmplx.h \ - oct-convn.h \ - oct-env.h \ - oct-fftw.h \ - oct-glob.h \ - oct-group.h \ - oct-inttypes.h \ - oct-locbuf.h \ - oct-md5.h \ - oct-mem.h \ - oct-mutex.h \ - oct-norm.h \ - oct-openmp.h \ - oct-passwd.h \ - oct-rand.h \ - oct-refcount.h \ - oct-rl-edit.h \ - oct-rl-hist.h \ - oct-shlib.h \ - oct-sort.h \ - oct-sparse.h \ - oct-spparms.h \ - oct-syscalls.h \ - oct-time.h \ - oct-uname.h \ - pathlen.h \ - pathsearch.h \ - randgamma.h \ - randmtzig.h \ - randpoisson.h \ - regexp.h \ - singleton-cleanup.h \ - sparse-sort.h \ - sparse-util.h \ - statdefs.h \ - str-vec.h \ - sun-utils.h \ - sysdir.h \ - syswait.h \ - $(MATRIX_INC) +EXTRA_DIST = -PRIVATE_INCS = \ - oct-glob.h - -OTHER_INC = \ - intNDArray.cc \ - kpse.cc \ - mx-inlines.cc - -include vx-op-inc.mk -include mx-op-inc.mk -include smx-op-inc.mk - -$(srcdir)/vx-op-inc.mk: $(srcdir)/config-ops.sh $(srcdir)/mk-ops.awk $(srcdir)/vx-ops - $(srcdir)/config-ops.sh $(top_srcdir) vx inc - -$(srcdir)/mx-op-inc.mk: $(srcdir)/config-ops.sh $(srcdir)/mk-ops.awk $(srcdir)/mx-ops - $(srcdir)/config-ops.sh $(top_srcdir) mx inc - -$(srcdir)/smx-op-inc.mk: $(srcdir)/config-ops.sh $(srcdir)/sparse-mk-ops.awk $(srcdir)/sparse-mx-ops - $(srcdir)/config-ops.sh $(top_srcdir) smx inc +DISTCLEANFILES = BUILT_INCS = \ - mx-ops.h \ + operators/mx-ops.h \ $(OPT_INC) \ $(MX_OP_INC) \ $(VX_OP_INC) \ @@ -286,241 +55,55 @@ BUILT_SOURCES = $(BUILT_INCS) -TEMPLATE_SRC = \ - Array.cc \ - DiagArray2.cc \ - MArray.cc \ - MDiagArray2.cc \ - base-lu.cc \ - base-qr.cc \ - bsxfun-defs.cc \ - eigs-base.cc \ - oct-sort.cc \ - sparse-base-chol.cc \ - sparse-base-lu.cc \ - sparse-dmsolve.cc +octinclude_HEADERS = \ + $(ARRAY_INC) \ + $(NUMERIC_INC) \ + $(OPERATORS_INC) \ + $(SYSTEM_INC) \ + $(UTIL_INC) \ + $(OTHER_INC) \ + $(TEMPLATE_SRC) -TI_SRC = \ - Array-C.cc \ - Array-b.cc \ - Array-ch.cc \ - Array-d.cc \ - Array-f.cc \ - Array-fC.cc \ - Array-i.cc \ - Array-idx-vec.cc \ - Array-s.cc \ - Array-str.cc \ - Array-voidp.cc \ - MArray-C.cc \ - MArray-d.cc \ - MArray-f.cc \ - MArray-fC.cc \ - MArray-i.cc \ - MArray-s.cc \ - MSparse-C.cc \ - MSparse-d.cc \ - Sparse-C.cc \ - Sparse-b.cc \ - Sparse-d.cc \ - oct-inttypes.cc +nodist_octinclude_HEADERS = \ + $(BUILT_INCS) + +noinst_LTLIBRARIES = -MATRIX_SRC = \ - Array-util.cc \ - CColVector.cc \ - CDiagMatrix.cc \ - CMatrix.cc \ - CNDArray.cc \ - CRowVector.cc \ - CSparse.cc \ - CmplxAEPBAL.cc \ - CmplxCHOL.cc \ - CmplxGEPBAL.cc \ - CmplxHESS.cc \ - CmplxLU.cc \ - CmplxQR.cc \ - CmplxQRP.cc \ - CmplxSCHUR.cc \ - CmplxSVD.cc \ - EIG.cc \ - MSparse.cc \ - MatrixType.cc \ - PermMatrix.cc \ - Sparse.cc \ - SparseCmplxCHOL.cc \ - SparseCmplxLU.cc \ - SparseCmplxQR.cc \ - SparseQR.cc \ - SparsedbleCHOL.cc \ - SparsedbleLU.cc \ - boolMatrix.cc \ - boolNDArray.cc \ - boolSparse.cc \ - chMatrix.cc \ - chNDArray.cc \ - dim-vector.cc \ - dColVector.cc \ - dDiagMatrix.cc \ - dMatrix.cc \ - dNDArray.cc \ - dRowVector.cc \ - dSparse.cc \ - dbleAEPBAL.cc \ - dbleCHOL.cc \ - dbleGEPBAL.cc \ - dbleHESS.cc \ - dbleLU.cc \ - dbleQR.cc \ - dbleQRP.cc \ - dbleSCHUR.cc \ - dbleSVD.cc \ - fCColVector.cc \ - fCDiagMatrix.cc \ - fCMatrix.cc \ - fCNDArray.cc \ - fCRowVector.cc \ - fCmplxAEPBAL.cc \ - fCmplxCHOL.cc \ - fCmplxGEPBAL.cc \ - fCmplxHESS.cc \ - fCmplxLU.cc \ - fCmplxQR.cc \ - fCmplxQRP.cc \ - fCmplxSCHUR.cc \ - fCmplxSVD.cc \ - fColVector.cc \ - fDiagMatrix.cc \ - fEIG.cc \ - fMatrix.cc \ - fNDArray.cc \ - fRowVector.cc \ - floatAEPBAL.cc \ - floatCHOL.cc \ - floatGEPBAL.cc \ - floatHESS.cc \ - floatLU.cc \ - floatQR.cc \ - floatQRP.cc \ - floatSCHUR.cc \ - floatSVD.cc \ - int16NDArray.cc \ - int32NDArray.cc \ - int64NDArray.cc \ - int8NDArray.cc \ - uint16NDArray.cc \ - uint32NDArray.cc \ - uint64NDArray.cc \ - uint8NDArray.cc +## C++ files that are #included, not compiled +OTHER_INC = -octlib_LTLIBRARIES = liboctave.la +## C++ files with templates that are #included, not compiled +TEMPLATE_SRC = -LIBOCTAVE_CXX_SOURCES = \ - CollocWt.cc \ - DASPK.cc \ - DASRT.cc \ - DASSL.cc \ - LSODE.cc \ - ODES.cc \ - Quad.cc \ - Range.cc \ - data-conv.cc \ - dir-ops.cc \ - file-ops.cc \ - file-stat.cc \ - glob-match.cc \ - idx-vector.cc \ - lo-array-gripes.cc \ - lo-ieee.cc \ - lo-mappers.cc \ - lo-specfun.cc \ - lo-sysdep.cc \ - lo-utils.cc \ - mach-info.cc \ - oct-alloc.cc \ - oct-convn.cc \ - oct-env.cc \ - oct-fftw.cc \ - oct-glob.cc \ - oct-group.cc \ - oct-locbuf.cc \ - oct-md5.cc \ - oct-mutex.cc \ - oct-norm.cc \ - oct-passwd.cc \ - oct-rand.cc \ - oct-shlib.cc \ - oct-spparms.cc \ - oct-syscalls.cc \ - oct-time.cc \ - oct-uname.cc \ - pathsearch.cc \ - regexp.cc \ - singleton-cleanup.cc \ - sparse-sort.cc \ - sparse-util.cc \ - str-vec.cc \ - $(TI_SRC) \ - $(MATRIX_SRC) +include array/module.mk +include numeric/module.mk +include operators/module.mk +include system/module.mk +include util/module.mk -include vx-op-src.mk -include mx-op-src.mk -include smx-op-src.mk - -$(srcdir)/vx-op-src.mk: $(srcdir)/config-ops.sh $(srcdir)/mk-ops.awk $(srcdir)/vx-ops - $(srcdir)/config-ops.sh $(top_srcdir) vx src - -$(srcdir)/mx-op-src.mk: $(srcdir)/config-ops.sh $(srcdir)/mk-ops.awk $(srcdir)/mx-ops - $(srcdir)/config-ops.sh $(top_srcdir) mx src - -$(srcdir)/smx-op-src.mk: $(srcdir)/config-ops.sh $(srcdir)/sparse-mk-ops.awk $(srcdir)/sparse-mx-ops - $(srcdir)/config-ops.sh $(top_srcdir) smx src - -BUILT_LIBOCTAVE_CXX_SOURCES = \ - $(MX_OP_SRC) \ - $(VX_OP_SRC) \ - $(SMX_OP_SRC) +## liboctave merely collects a bunch of compiled convenience libraries. +## It has no source code itself. +liboctave_la_SOURCES = -LIBOCTAVE_C_SOURCES = \ - f2c-main.c \ - lo-cieee.c \ - lo-cutils.c \ - randgamma.c \ - randmtzig.c \ - randpoisson.c \ - tempnam.c \ - tempname.c - -LIBOCT_READLINE_CXX_SOURCES = cmd-edit.cc cmd-hist.cc - -LIBOCT_READLINE_C_SOURCES = oct-rl-edit.c oct-rl-hist.c - -LIBOCT_READLINE_SOURCES = $(LIBOCT_READLINE_CXX_SOURCES) $(LIBOCT_READLINE_C_SOURCES) - -liboctave_la_SOURCES = \ - $(LIBOCTAVE_CXX_SOURCES) \ - $(LIBOCTAVE_C_SOURCES) \ - $(LIBOCTAVE_SOURCES) \ - $(LIBOCT_READLINE_SOURCES) \ - $(LIBOCT_PATHSEARCH_SOURCES) - -nodist_liboctave_la_SOURCES = \ - $(BUILT_LIBOCTAVE_CXX_SOURCES) +liboctave_la_CPPFLAGS = @OCTAVE_DLL_DEFS@ $(AM_CPPFLAGS) include link-deps.mk +# Dummy C++ source to force C++ linking. +nodist_EXTRA_liboctave_la_SOURCES = dummy.cc + liboctave_la_LIBADD = \ - ../libcruft/libcruft.la \ + array/libarray.la \ + cruft/libcruft.la \ + cruft/ranlib/libranlib.la \ + numeric/libnumeric.la \ + operators/liboperators.la \ + system/libsystem.la \ + util/libutil.la \ + $(top_builddir)/libgnu/libgnu.la \ $(LIBOCTAVE_LINK_DEPS) -liboctave_la_CPPFLAGS = \ - @OCTAVE_DLL_DEFS@ \ - $(SPARSE_XCPPFLAGS) \ - $(FFTW_XCPPFLAGS) \ - $(ARPACK_CPPFLAGS) \ - $(AM_CPPFLAGS) - -# Increment these as needed and according to the rules in the libtool -# manual: +# Increment these as needed and according to the rules in the libtool manual: liboctave_current = 1 liboctave_revision = 1 liboctave_age = 0 @@ -533,32 +116,5 @@ -bindir $(bindir) \ $(LIBOCTAVE_LINK_OPTS) -octinclude_HEADERS = \ - $(INCS) \ - $(OTHER_INC) \ - $(TEMPLATE_SRC) \ - $(EXTRA_HEADERS) - -nodist_octinclude_HEADERS = \ - $(BUILT_INCS) - -$(OPT_INC) : %.h : %.in $(top_srcdir)/build-aux/mk-opts.pl - @echo making $@ from $< - @$(PERL) $(top_srcdir)/build-aux/mk-opts.pl --opt-class-header $< > $@-t - mv $@-t $@ +DISTCLEANFILES += $(BUILT_INCS) -$(VX_OP_INC) $(VX_OP_SRC) : $(srcdir)/mk-ops.awk vx-ops - $(AWK) -f $(srcdir)/mk-ops.awk prefix=vx $(srcdir)/vx-ops - -$(MX_OP_INC) $(MX_OP_SRC) : $(srcdir)/mk-ops.awk mx-ops - $(AWK) -f $(srcdir)/mk-ops.awk prefix=mx $(srcdir)/mx-ops - -$(SMX_OP_INC) $(SMX_OP_SRC) : $(srcdir)/sparse-mk-ops.awk sparse-mx-ops - $(AWK) -f $(srcdir)/sparse-mk-ops.awk prefix=smx $(srcdir)/sparse-mx-ops - -mx-ops.h : $(srcdir)/mk-ops.awk mx-ops - $(AWK) -f $(srcdir)/mk-ops.awk prefix=mx make_inclusive_header=mx-ops.h $(srcdir)/mx-ops > $@-t - mv $@-t $@ - -DISTCLEANFILES = $(BUILT_INCS) $(BUILT_LIBOCTAVE_CXX_SOURCES) -
rename from liboctave/CDiagMatrix.cc rename to liboctave/array/CDiagMatrix.cc --- a/liboctave/CDiagMatrix.cc +++ b/liboctave/array/CDiagMatrix.cc @@ -236,13 +236,13 @@ DiagMatrix ComplexDiagMatrix::abs (void) const { - return DiagMatrix (diag ().abs (), rows (), columns ()); + return DiagMatrix (extract_diag ().abs (), rows (), columns ()); } ComplexDiagMatrix conj (const ComplexDiagMatrix& a) { - return ComplexDiagMatrix (conj (a.diag ()), a.rows (), a.columns ()); + return ComplexDiagMatrix (conj (a.extract_diag ()), a.rows (), a.columns ()); } // resize is the destructive analog for this one @@ -546,7 +546,7 @@ double ComplexDiagMatrix::rcond (void) const { - ColumnVector av = diag (0).map<double> (std::abs); + ColumnVector av = extract_diag (0).map<double> (std::abs); double amx = av.max (), amn = av.min (); return amx == 0 ? 0.0 : amn / amx; }
rename from liboctave/CDiagMatrix.h rename to liboctave/array/CDiagMatrix.h --- a/liboctave/CDiagMatrix.h +++ b/liboctave/array/CDiagMatrix.h @@ -120,8 +120,8 @@ // other operations - ComplexColumnVector diag (octave_idx_type k = 0) const - { return MDiagArray2<Complex>::diag (k); } + ComplexColumnVector extract_diag (octave_idx_type k = 0) const + { return MDiagArray2<Complex>::extract_diag (k); } ComplexDET determinant (void) const; double rcond (void) const;
rename from liboctave/CMatrix.cc rename to liboctave/array/CMatrix.cc --- a/liboctave/CMatrix.cc +++ b/liboctave/array/CMatrix.cc @@ -1183,7 +1183,7 @@ ComplexMatrix U = result.left_singular_matrix (); ComplexMatrix V = result.right_singular_matrix (); - ColumnVector sigma = S.diag (); + ColumnVector sigma = S.extract_diag (); octave_idx_type r = sigma.length () - 1; octave_idx_type nr = rows (); @@ -1786,15 +1786,17 @@ else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) { double anorm = -1.0; - ComplexMatrix atmp = *this; - Complex *tmp_data = atmp.fortran_vec (); if (typ == MatrixType::Hermitian) { octave_idx_type info = 0; char job = 'L'; - anorm = atmp.abs ().sum (). - row(static_cast<octave_idx_type>(0)).max (); + + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + anorm = atmp.abs().sum(). + row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1829,6 +1831,9 @@ { octave_idx_type info = 0; + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + Array<octave_idx_type> ipvt (dim_vector (nr, 1)); octave_idx_type *pipvt = ipvt.fortran_vec (); @@ -2098,9 +2103,11 @@ { info = 0; char job = 'L'; + ComplexMatrix atmp = *this; Complex *tmp_data = atmp.fortran_vec (); - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (zpotrf, ZPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info
rename from liboctave/DiagArray2.cc rename to liboctave/array/DiagArray2.cc --- a/liboctave/DiagArray2.cc +++ b/liboctave/array/DiagArray2.cc @@ -50,6 +50,13 @@ Array<T> DiagArray2<T>::diag (octave_idx_type k) const { + return extract_diag (k); +} + +template <class T> +Array<T> +DiagArray2<T>::extract_diag (octave_idx_type k) const +{ Array<T> d; if (k == 0)
rename from liboctave/DiagArray2.h rename to liboctave/array/DiagArray2.h --- a/liboctave/DiagArray2.h +++ b/liboctave/array/DiagArray2.h @@ -64,7 +64,7 @@ template <class U> DiagArray2 (const DiagArray2<U>& a) - : Array<T> (a.diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { } + : Array<T> (a.extract_diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { } ~DiagArray2 (void) { } @@ -97,7 +97,12 @@ dim_vector dims (void) const { return dim_vector (d1, d2); } - Array<T> diag (octave_idx_type k = 0) const; + Array<T> diag (octave_idx_type k = 0) const GCC_ATTR_DEPRECATED; + Array<T> extract_diag (octave_idx_type k = 0) const; + DiagArray2<T> build_diag_matrix () const + { + return DiagArray2<T> (array_value ()); + } // Warning: the non-const two-index versions will silently ignore assignments // to off-diagonal elements.
rename from liboctave/MDiagArray2.h rename to liboctave/array/MDiagArray2.h --- a/liboctave/MDiagArray2.h +++ b/liboctave/array/MDiagArray2.h @@ -91,7 +91,7 @@ } MArray<T> diag (octave_idx_type k = 0) const - { return DiagArray2<T>::diag (k); } + { return DiagArray2<T>::extract_diag (k); } MDiagArray2<T> transpose (void) const { return DiagArray2<T>::transpose (); } MDiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const { return DiagArray2<T>::hermitian (fcn); }
rename from liboctave/Sparse.cc rename to liboctave/array/Sparse.cc --- a/liboctave/Sparse.cc +++ b/liboctave/array/Sparse.cc @@ -323,9 +323,10 @@ if (n == 1 && a(0) != T ()) { change_capacity (nzm > 1 ? nzm : 1); - xcidx (0) = 0; - xridx (0) = r(0); - xdata (0) = a(0); + xcidx(0) = 0; + xridx(0) = r(0); + xdata(0) = a(0); + for (octave_idx_type j = 0; j < nc; j++) xcidx (j+1) = j >= c(0); } @@ -495,8 +496,8 @@ new_nz += rd[i-1] != rd[i]; // Allocate result. change_capacity (nzm > new_nz ? nzm : new_nz); - xcidx (0) = 0; - xcidx (1) = new_nz; + xcidx(0) = 0; + xcidx(1) = new_nz; octave_idx_type *rri = ridx (); T *rrd = data (); @@ -1253,7 +1254,7 @@ else { const Sparse<T> tmp = *this; - octave_idx_type lbi = tmp.cidx (lb), ubi = tmp.cidx (ub), + octave_idx_type lbi = tmp.cidx(lb), ubi = tmp.cidx(ub), new_nz = nz - (ubi - lbi); *this = Sparse<T> (nr, nc - (ub - lb), new_nz); @@ -1296,20 +1297,20 @@ tmpl.nnz () + tmpu.nnz ()); for (octave_idx_type j = 0, k = 0; j < nc; j++) { - for (octave_idx_type i = tmpl.cidx (j); i < tmpl.cidx (j+1); + for (octave_idx_type i = tmpl.cidx(j); i < tmpl.cidx(j+1); i++) { - xdata (k) = tmpl.data (i); - xridx (k++) = tmpl.ridx (i); + xdata(k) = tmpl.data(i); + xridx(k++) = tmpl.ridx(i); } - for (octave_idx_type i = tmpu.cidx (j); i < tmpu.cidx (j+1); + for (octave_idx_type i = tmpu.cidx(j); i < tmpu.cidx(j+1); i++) { - xdata (k) = tmpu.data (i); - xridx (k++) = tmpu.ridx (i) + lb; + xdata(k) = tmpu.data(i); + xridx(k++) = tmpu.ridx(i) + lb; } - xcidx (j+1) = k; + xcidx(j+1) = k; } } }
rename from liboctave/boolSparse.cc rename to liboctave/array/boolSparse.cc --- a/liboctave/boolSparse.cc +++ b/liboctave/array/boolSparse.cc @@ -29,7 +29,6 @@ #include <iostream> #include <vector> -#include "config.h" #include "quit.h" #include "lo-ieee.h" #include "lo-mappers.h"
rename from liboctave/dDiagMatrix.cc rename to liboctave/array/dDiagMatrix.cc --- a/liboctave/dDiagMatrix.cc +++ b/liboctave/array/dDiagMatrix.cc @@ -141,19 +141,19 @@ DiagMatrix DiagMatrix::abs (void) const { - return DiagMatrix (diag ().abs (), rows (), columns ()); + return DiagMatrix (extract_diag ().abs (), rows (), columns ()); } DiagMatrix real (const ComplexDiagMatrix& a) { - return DiagMatrix (real (a.diag ()), a.rows (), a.cols ()); + return DiagMatrix (real (a.extract_diag ()), a.rows (), a.cols ()); } DiagMatrix imag (const ComplexDiagMatrix& a) { - return DiagMatrix (imag (a.diag ()), a.rows (), a.cols ()); + return DiagMatrix (imag (a.extract_diag ()), a.rows (), a.cols ()); } Matrix @@ -362,7 +362,7 @@ double DiagMatrix::rcond (void) const { - ColumnVector av = diag (0).map<double> (fabs); + ColumnVector av = extract_diag (0).map<double> (fabs); double amx = av.max (), amn = av.min (); return amx == 0 ? 0.0 : amn / amx; }
rename from liboctave/dDiagMatrix.h rename to liboctave/array/dDiagMatrix.h --- a/liboctave/dDiagMatrix.h +++ b/liboctave/array/dDiagMatrix.h @@ -98,8 +98,8 @@ // other operations - ColumnVector diag (octave_idx_type k = 0) const - { return MDiagArray2<double>::diag (k); } + ColumnVector extract_diag (octave_idx_type k = 0) const + { return MDiagArray2<double>::extract_diag (k); } DET determinant (void) const; double rcond (void) const;
rename from liboctave/dMatrix.cc rename to liboctave/array/dMatrix.cc --- a/liboctave/dMatrix.cc +++ b/liboctave/array/dMatrix.cc @@ -856,7 +856,7 @@ Matrix U = result.left_singular_matrix (); Matrix V = result.right_singular_matrix (); - ColumnVector sigma = S.diag (); + ColumnVector sigma = S.extract_diag (); octave_idx_type r = sigma.length () - 1; octave_idx_type nr = rows (); @@ -1454,15 +1454,17 @@ else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) { double anorm = -1.0; - Matrix atmp = *this; - double *tmp_data = atmp.fortran_vec (); if (typ == MatrixType::Hermitian) { octave_idx_type info = 0; char job = 'L'; - anorm = atmp.abs ().sum (). - row(static_cast<octave_idx_type>(0)).max (); + + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + anorm = atmp.abs().sum(). + row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1495,6 +1497,9 @@ { octave_idx_type info = 0; + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + Array<octave_idx_type> ipvt (dim_vector (nr, 1)); octave_idx_type *pipvt = ipvt.fortran_vec (); @@ -1760,9 +1765,11 @@ { info = 0; char job = 'L'; + Matrix atmp = *this; double *tmp_data = atmp.fortran_vec (); - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1838,8 +1845,9 @@ Matrix atmp = *this; double *tmp_data = atmp.fortran_vec (); - if (anorm < 0.) - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + if(anorm < 0.) + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); Array<double> z (dim_vector (4 * nc, 1)); double *pz = z.fortran_vec ();
rename from liboctave/fCDiagMatrix.cc rename to liboctave/array/fCDiagMatrix.cc --- a/liboctave/fCDiagMatrix.cc +++ b/liboctave/array/fCDiagMatrix.cc @@ -236,13 +236,13 @@ FloatDiagMatrix FloatComplexDiagMatrix::abs (void) const { - return FloatDiagMatrix (diag ().abs (), rows (), columns ()); + return FloatDiagMatrix (extract_diag ().abs (), rows (), columns ()); } FloatComplexDiagMatrix conj (const FloatComplexDiagMatrix& a) { - return FloatComplexDiagMatrix (conj (a.diag ()), a.rows (), a.columns ()); + return FloatComplexDiagMatrix (conj (a.extract_diag ()), a.rows (), a.columns ()); } // resize is the destructive analog for this one @@ -546,7 +546,7 @@ float FloatComplexDiagMatrix::rcond (void) const { - FloatColumnVector av = diag (0).map<float> (std::abs); + FloatColumnVector av = extract_diag (0).map<float> (std::abs); float amx = av.max (), amn = av.min (); return amx == 0 ? 0.0f : amn / amx; }
rename from liboctave/fCDiagMatrix.h rename to liboctave/array/fCDiagMatrix.h --- a/liboctave/fCDiagMatrix.h +++ b/liboctave/array/fCDiagMatrix.h @@ -120,8 +120,8 @@ // other operations - FloatComplexColumnVector diag (octave_idx_type k = 0) const - { return MDiagArray2<FloatComplex>::diag (k); } + FloatComplexColumnVector extract_diag (octave_idx_type k = 0) const + { return MDiagArray2<FloatComplex>::extract_diag (k); } FloatComplexDET determinant (void) const; float rcond (void) const;
rename from liboctave/fCMatrix.cc rename to liboctave/array/fCMatrix.cc --- a/liboctave/fCMatrix.cc +++ b/liboctave/array/fCMatrix.cc @@ -1185,7 +1185,7 @@ FloatComplexMatrix U = result.left_singular_matrix (); FloatComplexMatrix V = result.right_singular_matrix (); - FloatColumnVector sigma = S.diag (); + FloatColumnVector sigma = S.extract_diag (); octave_idx_type r = sigma.length () - 1; octave_idx_type nr = rows (); @@ -1782,15 +1782,17 @@ else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) { float anorm = -1.0; - FloatComplexMatrix atmp = *this; - FloatComplex *tmp_data = atmp.fortran_vec (); if (typ == MatrixType::Hermitian) { octave_idx_type info = 0; char job = 'L'; - anorm = atmp.abs ().sum (). - row(static_cast<octave_idx_type>(0)).max (); + + FloatComplexMatrix atmp = *this; + FloatComplex *tmp_data = atmp.fortran_vec (); + + anorm = atmp.abs().sum(). + row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1825,6 +1827,9 @@ { octave_idx_type info = 0; + FloatComplexMatrix atmp = *this; + FloatComplex *tmp_data = atmp.fortran_vec (); + Array<octave_idx_type> ipvt (dim_vector (nr, 1)); octave_idx_type *pipvt = ipvt.fortran_vec (); @@ -2094,9 +2099,11 @@ { info = 0; char job = 'L'; + FloatComplexMatrix atmp = *this; FloatComplex *tmp_data = atmp.fortran_vec (); - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (cpotrf, CPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info
rename from liboctave/fDiagMatrix.cc rename to liboctave/array/fDiagMatrix.cc --- a/liboctave/fDiagMatrix.cc +++ b/liboctave/array/fDiagMatrix.cc @@ -141,19 +141,19 @@ FloatDiagMatrix FloatDiagMatrix::abs (void) const { - return FloatDiagMatrix (diag ().abs (), rows (), columns ()); + return FloatDiagMatrix (extract_diag ().abs (), rows (), columns ()); } FloatDiagMatrix real (const FloatComplexDiagMatrix& a) { - return FloatDiagMatrix (real (a.diag ()), a.rows (), a.columns ()); + return FloatDiagMatrix (real (a.extract_diag ()), a.rows (), a.columns ()); } FloatDiagMatrix imag (const FloatComplexDiagMatrix& a) { - return FloatDiagMatrix (imag (a.diag ()), a.rows (), a.columns ()); + return FloatDiagMatrix (imag (a.extract_diag ()), a.rows (), a.columns ()); } FloatMatrix @@ -362,7 +362,7 @@ float FloatDiagMatrix::rcond (void) const { - FloatColumnVector av = diag (0).map<float> (fabsf); + FloatColumnVector av = extract_diag (0).map<float> (fabsf); float amx = av.max (), amn = av.min (); return amx == 0 ? 0.0f : amn / amx; }
rename from liboctave/fDiagMatrix.h rename to liboctave/array/fDiagMatrix.h --- a/liboctave/fDiagMatrix.h +++ b/liboctave/array/fDiagMatrix.h @@ -98,8 +98,8 @@ // other operations - FloatColumnVector diag (octave_idx_type k = 0) const - { return MDiagArray2<float>::diag (k); } + FloatColumnVector extract_diag (octave_idx_type k = 0) const + { return MDiagArray2<float>::extract_diag (k); } FloatDET determinant (void) const; float rcond (void) const;
rename from liboctave/fMatrix.cc rename to liboctave/array/fMatrix.cc --- a/liboctave/fMatrix.cc +++ b/liboctave/array/fMatrix.cc @@ -856,7 +856,7 @@ FloatMatrix U = result.left_singular_matrix (); FloatMatrix V = result.right_singular_matrix (); - FloatColumnVector sigma = S.diag (); + FloatColumnVector sigma = S.extract_diag (); octave_idx_type r = sigma.length () - 1; octave_idx_type nr = rows (); @@ -1454,15 +1454,17 @@ else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) { float anorm = -1.0; - FloatMatrix atmp = *this; - float *tmp_data = atmp.fortran_vec (); if (typ == MatrixType::Hermitian) { octave_idx_type info = 0; char job = 'L'; - anorm = atmp.abs ().sum (). - row (static_cast<octave_idx_type>(0)).max (); + + FloatMatrix atmp = *this; + float *tmp_data = atmp.fortran_vec (); + + anorm = atmp.abs().sum(). + row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1495,6 +1497,9 @@ { octave_idx_type info = 0; + FloatMatrix atmp = *this; + float *tmp_data = atmp.fortran_vec (); + Array<octave_idx_type> ipvt (dim_vector (nr, 1)); octave_idx_type *pipvt = ipvt.fortran_vec (); @@ -1760,9 +1765,11 @@ { info = 0; char job = 'L'; + FloatMatrix atmp = *this; float *tmp_data = atmp.fortran_vec (); - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, tmp_data, nr, info @@ -1838,8 +1845,9 @@ FloatMatrix atmp = *this; float *tmp_data = atmp.fortran_vec (); - if (anorm < 0.) - anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); + + if(anorm < 0.) + anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); Array<float> z (dim_vector (4 * nc, 1)); float *pz = z.fortran_vec ();
new file mode 100644 --- /dev/null +++ b/liboctave/array/module.mk @@ -0,0 +1,143 @@ +EXTRA_DIST += \ + array/module.mk + +ARRAY_INC = \ + array/Array2.h \ + array/Array3.h \ + array/Array.h \ + array/ArrayN.h \ + array/Array-util.h \ + array/boolMatrix.h \ + array/boolNDArray.h \ + array/boolSparse.h \ + array/CColVector.h \ + array/CDiagMatrix.h \ + array/chMatrix.h \ + array/chNDArray.h \ + array/CMatrix.h \ + array/CNDArray.h \ + array/CRowVector.h \ + array/CSparse.h \ + array/dColVector.h \ + array/dDiagMatrix.h \ + array/DiagArray2.h \ + array/dim-vector.h \ + array/dMatrix.h \ + array/dNDArray.h \ + array/dRowVector.h \ + array/dSparse.h \ + array/fCColVector.h \ + array/fCDiagMatrix.h \ + array/fCMatrix.h \ + array/fCNDArray.h \ + array/fColVector.h \ + array/fCRowVector.h \ + array/fDiagMatrix.h \ + array/fMatrix.h \ + array/fNDArray.h \ + array/fRowVector.h \ + array/idx-vector.h \ + array/int16NDArray.h \ + array/int32NDArray.h \ + array/int64NDArray.h \ + array/int8NDArray.h \ + array/intNDArray.h \ + array/MArray2.h \ + array/MArray-decl.h \ + array/MArray-defs.h \ + array/MArray.h \ + array/MArrayN.h \ + array/Matrix.h \ + array/MatrixType.h \ + array/MDiagArray2.h \ + array/MSparse-defs.h \ + array/MSparse.h \ + array/PermMatrix.h \ + array/Range.h \ + array/Sparse.h \ + array/uint16NDArray.h \ + array/uint32NDArray.h \ + array/uint64NDArray.h \ + array/uint8NDArray.h + +ARRAY_SRC = \ + array/Array-b.cc \ + array/Array-C.cc \ + array/Array-ch.cc \ + array/Array-d.cc \ + array/Array-f.cc \ + array/Array-fC.cc \ + array/Array-i.cc \ + array/Array-idx-vec.cc \ + array/Array-s.cc \ + array/Array-str.cc \ + array/Array-util.cc \ + array/Array-voidp.cc \ + array/boolMatrix.cc \ + array/boolNDArray.cc \ + array/boolSparse.cc \ + array/CColVector.cc \ + array/CDiagMatrix.cc \ + array/chMatrix.cc \ + array/chNDArray.cc \ + array/CMatrix.cc \ + array/CNDArray.cc \ + array/CRowVector.cc \ + array/CSparse.cc \ + array/dColVector.cc \ + array/dDiagMatrix.cc \ + array/dim-vector.cc \ + array/dMatrix.cc \ + array/dNDArray.cc \ + array/dRowVector.cc \ + array/dSparse.cc \ + array/fCColVector.cc \ + array/fCDiagMatrix.cc \ + array/fCMatrix.cc \ + array/fCNDArray.cc \ + array/fColVector.cc \ + array/fCRowVector.cc \ + array/fDiagMatrix.cc \ + array/fMatrix.cc \ + array/fNDArray.cc \ + array/fRowVector.cc \ + array/idx-vector.cc \ + array/int16NDArray.cc \ + array/int32NDArray.cc \ + array/int64NDArray.cc \ + array/int8NDArray.cc \ + array/MArray-C.cc \ + array/MArray-d.cc \ + array/MArray-f.cc \ + array/MArray-fC.cc \ + array/MArray-i.cc \ + array/MArray-s.cc \ + array/MatrixType.cc \ + array/MSparse-C.cc \ + array/MSparse-d.cc \ + array/PermMatrix.cc \ + array/Range.cc \ + array/Sparse-b.cc \ + array/Sparse-C.cc \ + array/Sparse-d.cc \ + array/uint16NDArray.cc \ + array/uint32NDArray.cc \ + array/uint64NDArray.cc \ + array/uint8NDArray.cc + +TEMPLATE_SRC += \ + array/Array.cc \ + array/DiagArray2.cc \ + array/intNDArray.cc \ + array/MArray.cc \ + array/MDiagArray2.cc \ + array/MSparse.cc \ + array/Sparse.cc + +noinst_LTLIBRARIES += array/libarray.la + +array_libarray_la_SOURCES = $(ARRAY_SRC) +array_libarray_la_CPPFLAGS = \ + $(liboctave_la_CPPFLAGS) \ + $(SPARSE_XCPPFLAGS) +
rename from libcruft/Makefile.am rename to liboctave/cruft/Makefile.am --- a/libcruft/Makefile.am +++ b/liboctave/cruft/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's libcruft directory +# Makefile for Octave's liboctave/cruft directory # # Copyright (C) 1993-2012 John W. Eaton # @@ -26,7 +26,9 @@ AM_CPPFLAGS = \ -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu -octlib_LTLIBRARIES = libcruft.la +EXTRA_DIST = mkf77def.in + +noinst_LTLIBRARIES = libcruft.la libcruft_la_SOURCES = @@ -34,44 +36,12 @@ libcruft_la_FFLAGS = $(F77_INTEGER_8_FLAG) -libcruft_la_CPPFLAGS = \ - @CRUFT_DLL_DEFS@ \ - $(AM_CPPFLAGS) - -include link-deps.mk - -libcruft_la_LIBADD = \ - libranlib.la \ - $(top_builddir)/libgnu/libgnu.la \ - $(LIBCRUFT_LINK_DEPS) - -# Increment these as needed and according to the rules in the libtool -# manual: -libcruft_current = 1 -libcruft_revision = 0 -libcruft_age = 0 - -libcruft_version_info = $(libcruft_current):$(libcruft_revision):$(libcruft_age) - -libcruft_la_LDFLAGS = \ - -version-info $(libcruft_version_info) \ - $(NO_UNDEFINED_LDFLAG) \ - @XTRA_CRUFT_SH_LDFLAGS@ \ - -bindir $(bindir) \ - $(LIBCRUFT_LINK_OPTS) +libcruft_la_CPPFLAGS = @CRUFT_DLL_DEFS@ $(AM_CPPFLAGS) libcruft_la_DEPENDENCIES = cruft.def -noinst_LTLIBRARIES = libranlib.la - -libranlib_la_SOURCES = - -libranlib_la_DEPENDENCIES = ranlib.def - octinclude_HEADERS = -EXTRA_DIST = - include amos/module.mk include blas-xtra/module.mk include daspk/module.mk @@ -87,17 +57,14 @@ include slatec-err/module.mk include slatec-fn/module.mk +## Special rules for files which must be built before compilation cruft.def: $(libcruft_la_SOURCES) mkf77def chmod a+rx mkf77def ./mkf77def $(srcdir) $(libcruft_la_SOURCES) > $@-t mv $@-t $@ -ranlib.def: $(libranlib_la_SOURCES) mkf77def - chmod a+rx mkf77def - ./mkf77def $(srcdir) $(libranlib_la_SOURCES) > $@-t - mv $@-t $@ +DISTCLEANFILES = \ + cruft.def \ + ranlib/ranlib.def \ + $(nodist_libcruft_la_SOURCES) -EXTRA_DIST += mkf77def.in - -DISTCLEANFILES = cruft.def ranlib.def $(nodist_libcruft_la_SOURCES) -
rename from libcruft/ranlib/module.mk rename to liboctave/cruft/ranlib/module.mk --- a/libcruft/ranlib/module.mk +++ b/liboctave/cruft/ranlib/module.mk @@ -9,7 +9,7 @@ ranlib/tstgmn.for \ ranlib/tstmid.for -libranlib_la_SOURCES += \ +RANLIB_SRC = \ ranlib/advnst.f \ ranlib/genbet.f \ ranlib/genchi.f \ @@ -45,3 +45,16 @@ ranlib/sgamma.f \ ranlib/snorm.f \ ranlib/wrap.f + +noinst_LTLIBRARIES += ranlib/libranlib.la + +ranlib_libranlib_la_SOURCES = $(RANLIB_SRC) + +ranlib_libranlib_la_DEPENDENCIES = ranlib/ranlib.def + +## Special rules for files which must be built before compilation +ranlib/ranlib.def: $(RANLIB_SRC) mkf77def + chmod a+rx mkf77def + ./mkf77def $(srcdir) $(RANLIB_SRC) > $@-t + mv $@-t $@ +
rename from libcruft/slatec-fn/module.mk rename to liboctave/cruft/slatec-fn/module.mk --- a/libcruft/slatec-fn/module.mk +++ b/liboctave/cruft/slatec-fn/module.mk @@ -78,3 +78,4 @@ slatec-fn/derfc.f: slatec-fn/derfc.in.f Makefile $(SED) -e "${F77_ISNAN_MACRO}" < $< > $@-t mv $@-t $@ +
--- a/liboctave/link-deps.mk +++ b/liboctave/link-deps.mk @@ -1,6 +1,20 @@ -include $(top_srcdir)/libcruft/link-deps.mk +GNULIB_LINK_DEPS = \ + $(COPYSIGNF_LIBM)\ + $(COPYSIGN_LIBM)\ + $(FLOORF_LIBM)\ + $(FLOOR_LIBM)\ + $(GETHOSTNAME_LIB)\ + $(LIBSOCKET)\ + $(LIB_NANOSLEEP)\ + $(LIB_SELECT)\ + $(LTLIBINTL)\ + $(ROUNDF_LIBM)\ + $(ROUND_LIBM)\ + $(TRUNCF_LIBM)\ + $(TRUNC_LIBM) LIBOCTAVE_LINK_DEPS = \ + $(GNULIB_LINK_DEPS) \ $(SPARSE_XLIBS) \ $(ARPACK_LIBS) \ $(QRUPDATE_LIBS) \ @@ -13,6 +27,7 @@ $(REGEX_LIBS) \ $(DL_LIBS) \ $(PTHREAD_LIBS) \ + $(FLIBS) \ $(LIBS) LIBOCTAVE_LINK_OPTS = \ @@ -20,8 +35,3 @@ $(ARPACK_LDFLAGS) \ $(QRUPDATE_LDFLAGS) \ $(FFTW_XLDFLAGS) - -if AMCOND_LINK_ALL_DEPS - LIBOCTAVE_LINK_DEPS += $(LIBCRUFT_LINK_DEPS) - LIBOCTAVE_LINK_OPTS += $(LIBCRUFT_LINK_OPTS) -endif
rename from liboctave/CmplxLU.cc rename to liboctave/numeric/CmplxLU.cc --- a/liboctave/CmplxLU.cc +++ b/liboctave/numeric/CmplxLU.cc @@ -33,8 +33,8 @@ // Instantiate the base LU class for the types we need. -#include <base-lu.h> -#include <base-lu.cc> +#include "base-lu.h" +#include "base-lu.cc" template class base_lu <ComplexMatrix>;
rename from liboctave/SparseCmplxCHOL.h rename to liboctave/numeric/SparseCmplxCHOL.h --- a/liboctave/SparseCmplxCHOL.h +++ b/liboctave/numeric/SparseCmplxCHOL.h @@ -38,14 +38,13 @@ SparseComplexCHOL (void) : sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> () { } - SparseComplexCHOL (const SparseComplexMatrix& a, bool natural = true) : - sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> - (a, natural) { } + SparseComplexCHOL (const SparseComplexMatrix& a, bool natural = true, + bool force = false) : + sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> (a, natural, force) { } SparseComplexCHOL (const SparseComplexMatrix& a, octave_idx_type& info, - bool natural = true) : - sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> - (a, info, natural) { } + bool natural = true, bool force = false) : + sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> (a, info, natural, force) { } SparseComplexCHOL (const SparseComplexCHOL& a) : sparse_base_chol<SparseComplexMatrix, Complex, SparseMatrix> (a) { }
rename from liboctave/SparsedbleCHOL.h rename to liboctave/numeric/SparsedbleCHOL.h --- a/liboctave/SparsedbleCHOL.h +++ b/liboctave/numeric/SparsedbleCHOL.h @@ -35,12 +35,12 @@ SparseCHOL (void) : sparse_base_chol<SparseMatrix, double, SparseMatrix> () { } - SparseCHOL (const SparseMatrix& a, bool natural = true) : - sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, natural) { } + SparseCHOL (const SparseMatrix& a, bool natural = true, bool force = false) : + sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, natural, force) { } SparseCHOL (const SparseMatrix& a, octave_idx_type& info, - bool natural = true) : - sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, info, natural) { } + bool natural = false, bool force = false) : + sparse_base_chol<SparseMatrix, double, SparseMatrix> (a, info, natural, force) { } SparseCHOL (const SparseCHOL& a) : sparse_base_chol<SparseMatrix, double, SparseMatrix> (a) { }
rename from liboctave/dbleLU.cc rename to liboctave/numeric/dbleLU.cc --- a/liboctave/dbleLU.cc +++ b/liboctave/numeric/dbleLU.cc @@ -33,8 +33,8 @@ // Instantiate the base LU class for the types we need. -#include <base-lu.h> -#include <base-lu.cc> +#include "base-lu.h" +#include "base-lu.cc" template class base_lu <Matrix>;
rename from liboctave/fCmplxLU.cc rename to liboctave/numeric/fCmplxLU.cc --- a/liboctave/fCmplxLU.cc +++ b/liboctave/numeric/fCmplxLU.cc @@ -33,8 +33,8 @@ // Instantiate the base LU class for the types we need. -#include <base-lu.h> -#include <base-lu.cc> +#include "base-lu.h" +#include "base-lu.cc" template class base_lu <FloatComplexMatrix>;
rename from liboctave/floatLU.cc rename to liboctave/numeric/floatLU.cc --- a/liboctave/floatLU.cc +++ b/liboctave/numeric/floatLU.cc @@ -33,8 +33,8 @@ // Instantiate the base LU class for the types we need. -#include <base-lu.h> -#include <base-lu.cc> +#include "base-lu.h" +#include "base-lu.cc" template class base_lu <FloatMatrix>;
rename from liboctave/lo-mappers.cc rename to liboctave/numeric/lo-mappers.cc --- a/liboctave/lo-mappers.cc +++ b/liboctave/numeric/lo-mappers.cc @@ -279,10 +279,15 @@ return gnulib::copysignf (x, y); } +float xfloor (float x) +{ + return gnulib::floorf (x); +} + float xround (float x) { - return gnulib::round (x); + return gnulib::roundf (x); } float @@ -312,7 +317,9 @@ float xlog2 (float x) { -#if defined (HAVE_LOG2) +#if defined (HAVE_LOG2F) + return log2f (x); +#elif defined (HAVE_LOG2) return log2 (x); #else #if defined (M_LN2) @@ -340,7 +347,9 @@ float xexp2 (float x) { -#if defined (HAVE_EXP2) +#if defined (HAVE_EXP2F) + return exp2f (x); +#elif defined (HAVE_EXP2) return exp2 (x); #else #if defined (M_LN2)
rename from liboctave/lo-mappers.h rename to liboctave/numeric/lo-mappers.h --- a/liboctave/lo-mappers.h +++ b/liboctave/numeric/lo-mappers.h @@ -119,7 +119,7 @@ extern OCTAVE_API float xtrunc (float x); extern OCTAVE_API float xcopysign (float x, float y); inline float xceil (float x) { return ceilf (x); } -inline float xfloor (float x) { return floorf (x); } +extern OCTAVE_API float xfloor (float x); inline float arg (float x) { return atan2f (0.0f, x); } inline float conj (float x) { return x; } inline float fix (float x) { return xtrunc (x); } @@ -401,4 +401,11 @@ return retval; } +template <typename T> +T +xsignbit (T x) +{ + return signbit (x); +} + #endif
new file mode 100644 --- /dev/null +++ b/liboctave/numeric/module.mk @@ -0,0 +1,184 @@ +EXTRA_DIST += \ + numeric/module.mk \ + $(OPT_IN) + +OPT_INC = \ + numeric/DASPK-opts.h \ + numeric/DASRT-opts.h \ + numeric/DASSL-opts.h \ + numeric/LSODE-opts.h \ + numeric/Quad-opts.h + +OPT_IN = $(OPT_INC:.h=.in) + +NUMERIC_INC = \ + numeric/base-aepbal.h \ + numeric/base-dae.h \ + numeric/base-de.h \ + numeric/base-lu.h \ + numeric/base-min.h \ + numeric/base-qr.h \ + numeric/bsxfun-decl.h \ + numeric/bsxfun.h \ + numeric/CmplxAEPBAL.h \ + numeric/CmplxCHOL.h \ + numeric/CmplxGEPBAL.h \ + numeric/CmplxHESS.h \ + numeric/CmplxLU.h \ + numeric/CmplxQR.h \ + numeric/CmplxQRP.h \ + numeric/CmplxSCHUR.h \ + numeric/CmplxSVD.h \ + numeric/CollocWt.h \ + numeric/DAEFunc.h \ + numeric/DAE.h \ + numeric/DAERTFunc.h \ + numeric/DAERT.h \ + numeric/DASPK.h \ + numeric/DASRT.h \ + numeric/DASSL.h \ + numeric/dbleAEPBAL.h \ + numeric/dbleCHOL.h \ + numeric/dbleGEPBAL.h \ + numeric/dbleHESS.h \ + numeric/dbleLU.h \ + numeric/dbleQR.h \ + numeric/dbleQRP.h \ + numeric/dbleSCHUR.h \ + numeric/dbleSVD.h \ + numeric/DET.h \ + numeric/EIG.h \ + numeric/fCmplxAEPBAL.h \ + numeric/fCmplxCHOL.h \ + numeric/fCmplxGEPBAL.h \ + numeric/fCmplxHESS.h \ + numeric/fCmplxLU.h \ + numeric/fCmplxQR.h \ + numeric/fCmplxQRP.h \ + numeric/fCmplxSCHUR.h \ + numeric/fCmplxSVD.h \ + numeric/fEIG.h \ + numeric/floatAEPBAL.h \ + numeric/floatCHOL.h \ + numeric/floatGEPBAL.h \ + numeric/floatHESS.h \ + numeric/floatLU.h \ + numeric/floatQR.h \ + numeric/floatQRP.h \ + numeric/floatSCHUR.h \ + numeric/floatSVD.h \ + numeric/lo-mappers.h \ + numeric/lo-specfun.h \ + numeric/LSODE.h \ + numeric/oct-convn.h \ + numeric/oct-fftw.h \ + numeric/oct-norm.h \ + numeric/oct-rand.h \ + numeric/oct-spparms.h \ + numeric/ODEFunc.h \ + numeric/ODE.h \ + numeric/ODESFunc.h \ + numeric/ODES.h \ + numeric/Quad.h \ + numeric/randgamma.h \ + numeric/randmtzig.h \ + numeric/randpoisson.h \ + numeric/sparse-base-chol.h \ + numeric/sparse-base-lu.h \ + numeric/SparseCmplxCHOL.h \ + numeric/SparseCmplxLU.h \ + numeric/SparseCmplxQR.h \ + numeric/SparsedbleCHOL.h \ + numeric/SparsedbleLU.h \ + numeric/SparseQR.h + +NUMERIC_C_SRC = \ + numeric/randgamma.c \ + numeric/randmtzig.c \ + numeric/randpoisson.c + +NUMERIC_SRC = \ + numeric/CmplxAEPBAL.cc \ + numeric/CmplxCHOL.cc \ + numeric/CmplxGEPBAL.cc \ + numeric/CmplxHESS.cc \ + numeric/CmplxLU.cc \ + numeric/CmplxQR.cc \ + numeric/CmplxQRP.cc \ + numeric/CmplxSCHUR.cc \ + numeric/CmplxSVD.cc \ + numeric/CollocWt.cc \ + numeric/DASPK.cc \ + numeric/DASRT.cc \ + numeric/DASSL.cc \ + numeric/dbleAEPBAL.cc \ + numeric/dbleCHOL.cc \ + numeric/dbleGEPBAL.cc \ + numeric/dbleHESS.cc \ + numeric/dbleLU.cc \ + numeric/dbleQR.cc \ + numeric/dbleQRP.cc \ + numeric/dbleSCHUR.cc \ + numeric/dbleSVD.cc \ + numeric/EIG.cc \ + numeric/fCmplxAEPBAL.cc \ + numeric/fCmplxCHOL.cc \ + numeric/fCmplxGEPBAL.cc \ + numeric/fCmplxHESS.cc \ + numeric/fCmplxLU.cc \ + numeric/fCmplxQR.cc \ + numeric/fCmplxQRP.cc \ + numeric/fCmplxSCHUR.cc \ + numeric/fCmplxSVD.cc \ + numeric/fEIG.cc \ + numeric/floatAEPBAL.cc \ + numeric/floatCHOL.cc \ + numeric/floatGEPBAL.cc \ + numeric/floatHESS.cc \ + numeric/floatLU.cc \ + numeric/floatQR.cc \ + numeric/floatQRP.cc \ + numeric/floatSCHUR.cc \ + numeric/floatSVD.cc \ + numeric/lo-mappers.cc \ + numeric/lo-specfun.cc \ + numeric/LSODE.cc \ + numeric/oct-convn.cc \ + numeric/oct-fftw.cc \ + numeric/oct-norm.cc \ + numeric/oct-rand.cc \ + numeric/oct-spparms.cc \ + numeric/ODES.cc \ + numeric/Quad.cc \ + numeric/SparseCmplxCHOL.cc \ + numeric/SparseCmplxLU.cc \ + numeric/SparseCmplxQR.cc \ + numeric/SparsedbleCHOL.cc \ + numeric/SparsedbleLU.cc \ + numeric/SparseQR.cc \ + $(NUMERIC_C_SRC) + +TEMPLATE_SRC += \ + numeric/base-lu.cc \ + numeric/base-qr.cc \ + numeric/bsxfun-defs.cc \ + numeric/eigs-base.cc \ + numeric/sparse-base-chol.cc \ + numeric/sparse-base-lu.cc \ + numeric/sparse-dmsolve.cc + +## Special rules for sources which must be built before rest of compilation. +$(OPT_INC) : %.h : %.in $(top_srcdir)/build-aux/mk-opts.pl + @echo making $@ from $< + @$(PERL) $(top_srcdir)/build-aux/mk-opts.pl --opt-class-header $< > $@-t + mv $@-t $@ + +noinst_LTLIBRARIES += numeric/libnumeric.la + +numeric_libnumeric_la_SOURCES = $(NUMERIC_SRC) +numeric_libnumeric_la_CPPFLAGS = \ + $(liboctave_la_CPPFLAGS) \ + $(ARPACK_CPPFLAGS) \ + $(FFTW_XCPPFLAGS) \ + $(SPARSE_XCPPFLAGS) +
rename from liboctave/oct-rand.cc rename to liboctave/numeric/oct-rand.cc --- a/liboctave/oct-rand.cc +++ b/liboctave/numeric/oct-rand.cc @@ -658,7 +658,7 @@ retval = gamma_dist; else (*current_liboctave_error_handler) - ("rand: invalid distribution `%s'", d.c_str ()); + ("rand: invalid distribution '%s'", d.c_str ()); return retval; }
rename from liboctave/randmtzig.c rename to liboctave/numeric/randmtzig.c --- a/liboctave/randmtzig.c +++ b/liboctave/numeric/randmtzig.c @@ -260,7 +260,7 @@ int n = 0; /* Look for entropy in /dev/urandom */ - FILE* urandom =fopen ("/dev/urandom", "rb"); + FILE* urandom = fopen ("/dev/urandom", "rb"); if (urandom) { while (n < MT_N) @@ -400,8 +400,8 @@ static double randu53 (void) { - const uint32_t a=randi32 ()>>5; - const uint32_t b=randi32 ()>>6; + const uint32_t a = randi32 ()>>5; + const uint32_t b = randi32 ()>>6; return (a*67108864.0+b+0.4) * (1.0/9007199254740992.0); } @@ -593,7 +593,7 @@ # else /* !HAVE_X86_32 */ /* arbitrary mantissa (selected by NRANDI, with 1 bit for sign) */ const uint64_t r = NRANDI; - const int64_t rabs=r>>1; + const int64_t rabs = r>>1; const int idx = (int)(rabs&0xFF); const double x = ( r&1 ? -rabs : rabs) * wi[idx]; # endif /* !HAVE_X86_32 */
rename from liboctave/sparse-base-chol.cc rename to liboctave/numeric/sparse-base-chol.cc --- a/liboctave/sparse-base-chol.cc +++ b/liboctave/numeric/sparse-base-chol.cc @@ -80,9 +80,10 @@ template <class chol_type, class chol_elt, class p_type> octave_idx_type sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep::init - (const chol_type& a, bool natural, octave_idx_type nargout) + (const chol_type& a, bool natural, bool force) { volatile octave_idx_type info = 0; + #ifdef HAVE_CHOLMOD octave_idx_type a_nr = a.rows (); octave_idx_type a_nc = a.cols (); @@ -170,7 +171,7 @@ is_pd = cm->status == CHOLMOD_OK; info = (is_pd ? 0 : cm->status); - if (is_pd || nargout > 1) + if (is_pd || force) { BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; cond = CHOLMOD_NAME(rcond) (Lfactor, cm);
rename from liboctave/sparse-base-chol.h rename to liboctave/numeric/sparse-base-chol.h --- a/liboctave/sparse-base-chol.h +++ b/liboctave/numeric/sparse-base-chol.h @@ -41,19 +41,19 @@ perms (), cond (0) { } - sparse_base_chol_rep (const chol_type& a, const bool natural) + sparse_base_chol_rep (const chol_type& a, bool natural, bool force) : count (1), Lsparse (0), Common (), is_pd (false), minor_p (0), perms (), cond (0) { - init (a, natural); + init (a, natural, force); } sparse_base_chol_rep (const chol_type& a, octave_idx_type& info, - const bool natural) + bool natural, bool force) : count (1), Lsparse (0), Common (), is_pd (false), minor_p (0), perms (), cond (0) { - info = init (a, natural, info); + info = init (a, natural, force); } ~sparse_base_chol_rep (void) @@ -93,8 +93,7 @@ double cond; - octave_idx_type init (const chol_type& a, bool natural = true, - octave_idx_type nargout = 1); + octave_idx_type init (const chol_type& a, bool natural, bool force); void drop_zeros (const cholmod_sparse* S); @@ -111,18 +110,17 @@ sparse_base_chol_rep (void) : count (1), is_pd (false), minor_p (0), perms (), cond (0) { } - sparse_base_chol_rep (const chol_type& a, - const bool natural) + sparse_base_chol_rep (const chol_type& a, bool natural, bool force) : count (1), is_pd (false), minor_p (0), perms (), cond (0) { - init (a, natural); + init (a, natural, force); } sparse_base_chol_rep (const chol_type& a, octave_idx_type& info, - const bool natural) + bool natural, bool force) : count (1), is_pd (false), minor_p (0), perms (), cond (0) { - info = init (a, natural, info); + info = init (a, natural, force); } ~sparse_base_chol_rep (void) { } @@ -148,8 +146,7 @@ double cond; - octave_idx_type init (const chol_type& a, bool natural = true, - octave_idx_type nargout = 0); + octave_idx_type init (const chol_type& a, bool natural, bool force); // No copying! @@ -169,13 +166,14 @@ sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep ()) { } - sparse_base_chol (const chol_type& a, const bool n) + sparse_base_chol (const chol_type& a, bool natural, bool force) : rep (new typename - sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep (a, n)) + sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep (a, natural, force)) { } - sparse_base_chol (const chol_type& a, octave_idx_type& info, const bool n) - : rep (new typename sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep (a, info, n)) + sparse_base_chol (const chol_type& a, octave_idx_type& info, + bool natural, bool force) + : rep (new typename sparse_base_chol<chol_type, chol_elt, p_type>::sparse_base_chol_rep (a, info, natural, force)) { } sparse_base_chol (const sparse_base_chol<chol_type, chol_elt, p_type>& a)
rename from liboctave/sparse-dmsolve.cc rename to liboctave/numeric/sparse-dmsolve.cc --- a/liboctave/sparse-dmsolve.cc +++ b/liboctave/numeric/sparse-dmsolve.cc @@ -482,6 +482,8 @@ } return retval; #else + (*current_liboctave_error_handler) + ("CXSPARSE unavailable; cannot solve minimum norm problem"); return RT (); #endif }
rename from liboctave/config-ops.sh rename to liboctave/operators/config-ops.sh --- a/liboctave/config-ops.sh +++ b/liboctave/operators/config-ops.sh @@ -17,14 +17,14 @@ fi if [ $# -lt 1 ]; then - top_srcdir=".." + top_srcdir="../.." else top_srcdir="$1" fi move_if_change="$top_srcdir/build-aux/move-if-change" -liboctave_dir="$top_srcdir/liboctave" +liboctave_dir="$top_srcdir/liboctave/operators" mk_ops="$liboctave_dir/mk-ops.awk" sparse_mk_ops="$liboctave_dir/sparse-mk-ops.awk"
rename from liboctave/mk-ops.awk rename to liboctave/operators/mk-ops.awk --- a/liboctave/mk-ops.awk +++ b/liboctave/operators/mk-ops.awk @@ -93,13 +93,13 @@ if (list_cc_files) { - printf (" %s", cc_file); + printf (" operators/%s", cc_file); next; } if (list_h_files) { - printf (" %s", h_file); + printf (" operators/%s", h_file); next; }
new file mode 100644 --- /dev/null +++ b/liboctave/operators/module.mk @@ -0,0 +1,69 @@ +EXTRA_DIST += \ + operators/module.mk \ + operators/config-ops.sh \ + operators/mk-ops.awk \ + operators/mx-op-inc.mk \ + operators/mx-op-src.mk \ + operators/mx-ops \ + operators/smx-op-inc.mk \ + operators/smx-op-src.mk \ + operators/sparse-mk-ops.awk \ + operators/sparse-mx-ops \ + operators/vx-op-inc.mk \ + operators/vx-op-src.mk \ + operators/vx-ops + +include operators/vx-op-inc.mk +include operators/mx-op-inc.mk +include operators/smx-op-inc.mk + +include operators/vx-op-src.mk +include operators/mx-op-src.mk +include operators/smx-op-src.mk + +BUILT_LIBOPERATORS_SOURCES = \ + $(MX_OP_SRC) \ + $(VX_OP_SRC) \ + $(SMX_OP_SRC) + +OPERATORS_INC = \ + operators/mx-base.h \ + operators/mx-defs.h \ + operators/mx-ext.h \ + operators/mx-op-decl.h \ + operators/mx-op-defs.h \ + operators/Sparse-diag-op-defs.h \ + operators/Sparse-op-defs.h \ + operators/Sparse-perm-op-defs.h + +## There are no distributed source files in this directory +OPERATORS_SRC = + +TEMPLATE_SRC += \ + operators/mx-inlines.cc + +OP_SRCDIR = $(abs_top_srcdir)/liboctave/operators + +## Special rules for sources which must be built before rest of compilation. +$(VX_OP_INC) $(VX_OP_SRC) : operators/mk-ops.awk operators/vx-ops + (cd operators; $(AWK) -f $(OP_SRCDIR)/mk-ops.awk prefix=vx $(OP_SRCDIR)/vx-ops) + +$(MX_OP_INC) $(MX_OP_SRC) : operators/mk-ops.awk operators/mx-ops + (cd operators; $(AWK) -f $(OP_SRCDIR)/mk-ops.awk prefix=mx $(OP_SRCDIR)/mx-ops) + +$(SMX_OP_INC) $(SMX_OP_SRC) : operators/sparse-mk-ops.awk operators/sparse-mx-ops + (cd operators; $(AWK) -f $(OP_SRCDIR)/sparse-mk-ops.awk prefix=smx $(OP_SRCDIR)/sparse-mx-ops) + +operators/mx-ops.h : operators/mk-ops.awk operators/mx-ops + $(AWK) -f $(OP_SRCDIR)/mk-ops.awk prefix=mx make_inclusive_header=mx-ops.h $(OP_SRCDIR)/mx-ops > $@-t + mv $@-t $@ + +noinst_LTLIBRARIES += operators/liboperators.la + +operators_liboperators_la_SOURCES = $(OPERATORS_SRC) +nodist_operators_liboperators_la_SOURCES = $(BUILT_LIBOPERATORS_SOURCES) + +operators_liboperators_la_CPPFLAGS = $(liboctave_la_CPPFLAGS) + +DISTCLEANFILES += $(BUILT_LIBOPERATORS_SOURCES) +
rename from liboctave/mx-inlines.cc rename to liboctave/operators/mx-inlines.cc --- a/liboctave/mx-inlines.cc +++ b/liboctave/operators/mx-inlines.cc @@ -1086,7 +1086,7 @@ for (octave_idx_type i = 0; i < n-2; i++) { for (octave_idx_type j = i*m; j < i*m+m; j++) - r[j] = (v[j+m+m] - v[j+m]) + (v[j+m] - v[j]); + r[j] = (v[j+m+m] - v[j+m]) - (v[j+m] - v[j]); } break; default:
rename from liboctave/mx-ops rename to liboctave/operators/mx-ops --- a/liboctave/mx-ops +++ b/liboctave/operators/mx-ops @@ -16,7 +16,7 @@ # along with Octave; see the file COPYING. If not, see # <http://www.gnu.org/licenses/>. -# NOTE: if this file changes, you must run autogen.sh and configure to +# NOTE: if this file changes, you must run bootstrap and configure to # rebuild the source file lists for Make. # types
rename from liboctave/sparse-mk-ops.awk rename to liboctave/operators/sparse-mk-ops.awk --- a/liboctave/sparse-mk-ops.awk +++ b/liboctave/operators/sparse-mk-ops.awk @@ -92,13 +92,13 @@ if (list_cc_files) { - printf (" %s", cc_file); + printf (" operators/%s", cc_file); next; } if (list_h_files) { - printf (" %s", h_file); + printf (" operators/%s", h_file); next; }
rename from liboctave/sparse-mx-ops rename to liboctave/operators/sparse-mx-ops --- a/liboctave/sparse-mx-ops +++ b/liboctave/operators/sparse-mx-ops @@ -16,7 +16,7 @@ # along with Octave; see the file COPYING. If not, see # <http://www.gnu.org/licenses/>. -# NOTE: if this file changes, you must run autogen.sh and configure to +# NOTE: if this file changes, you must run bootstrap and configure to # rebuild the source file lists for Make. # types
rename from liboctave/vx-ops rename to liboctave/operators/vx-ops --- a/liboctave/vx-ops +++ b/liboctave/operators/vx-ops @@ -16,7 +16,7 @@ # along with Octave; see the file COPYING. If not, see # <http://www.gnu.org/licenses/>. -# NOTE: if this file changes, you must run autogen.sh and configure to +# NOTE: if this file changes, you must run bootstrap and configure to # rebuild the source file lists for Make. # types
rename from liboctave/file-ops.cc rename to liboctave/system/file-ops.cc --- a/liboctave/file-ops.cc +++ b/liboctave/system/file-ops.cc @@ -37,6 +37,7 @@ #include <unistd.h> #include "pathmax.h" +#include "canonicalize.h" #include "dir-ops.h" #include "file-ops.h" @@ -117,13 +118,13 @@ file_ops::tilde_expansion_hook file_ops::tilde_expansion_failure_hook = 0; // When non-null, this is a NULL terminated array of strings which are -// duplicates for a tilde prefix. Bash uses this to expand `=~' and -// `:~'. +// duplicates for a tilde prefix. Bash uses this to expand '=~' and +// ':~'. string_vector file_ops::tilde_additional_prefixes = default_prefixes; // When non-null, this is a NULL terminated array of strings which // match the end of a username, instead of just "/". Bash sets this -// to `:' and `=~'. +// to ':' and '=~'. string_vector file_ops::tilde_additional_suffixes = default_suffixes; // Find the start of a tilde expansion in S, and return the index @@ -221,7 +222,7 @@ if (f_len == 0 || filename[0] != '~') return filename; - // A leading `~/' or a bare `~' is *always* translated to the value + // A leading '~/' or a bare '~' is *always* translated to the value // of $HOME or the home directory of the current user, regardless of // any preexpansion hook.
new file mode 100644 --- /dev/null +++ b/liboctave/system/module.mk @@ -0,0 +1,43 @@ +EXTRA_DIST += \ + system/module.mk + +SYSTEM_INC = \ + system/dir-ops.h \ + system/file-ops.h \ + system/file-stat.h \ + system/lo-sysdep.h \ + system/mach-info.h \ + system/oct-env.h \ + system/oct-group.h \ + system/oct-openmp.h \ + system/oct-passwd.h \ + system/oct-syscalls.h \ + system/oct-time.h \ + system/oct-uname.h \ + system/pathlen.h \ + system/sysdir.h \ + system/syswait.h + +SYSTEM_C_SRC = \ + system/tempnam.c \ + system/tempname.c + +SYSTEM_SRC = \ + system/dir-ops.cc \ + system/file-ops.cc \ + system/file-stat.cc \ + system/lo-sysdep.cc \ + system/mach-info.cc \ + system/oct-env.cc \ + system/oct-group.cc \ + system/oct-passwd.cc \ + system/oct-syscalls.cc \ + system/oct-time.cc \ + system/oct-uname.cc \ + $(SYSTEM_C_SRC) + +noinst_LTLIBRARIES += system/libsystem.la + +system_libsystem_la_SOURCES = $(SYSTEM_SRC) +system_libsystem_la_CPPFLAGS = $(liboctave_la_CPPFLAGS) +
rename from liboctave/oct-env.cc rename to liboctave/system/oct-env.cc --- a/liboctave/oct-env.cc +++ b/liboctave/system/oct-env.cc @@ -234,7 +234,7 @@ } // Return a pretty pathname. If the first part of the pathname is the -// same as $HOME, then replace that with `~'. +// same as $HOME, then replace that with '~'. std::string octave_env::do_polite_directory_format (const std::string& name) const @@ -301,7 +301,7 @@ return false; } -// Return the `basename' of the pathname in STRING (the stuff after +// Return the 'basename' of the pathname in STRING (the stuff after // the last directory separator). If STRING is not a full pathname, // simply return it.
rename from liboctave/cmd-edit.cc rename to liboctave/util/cmd-edit.cc --- a/liboctave/cmd-edit.cc +++ b/liboctave/util/cmd-edit.cc @@ -1276,7 +1276,7 @@ // \a bell (ascii 07) // \d the date // \e escape (ascii 033) -// \h the hostname up to the first `.' +// \h the hostname up to the first '.' // \H the hostname // \n CRLF // \r CR
rename from liboctave/cmd-hist.cc rename to liboctave/util/cmd-hist.cc --- a/liboctave/cmd-hist.cc +++ b/liboctave/util/cmd-hist.cc @@ -69,6 +69,8 @@ void do_remove (int); + void do_clear (void); + int do_where (void) const; int do_length (void) const; @@ -201,6 +203,12 @@ ::octave_remove_history (n); } +void +gnu_history::do_clear (void) +{ + ::octave_clear_history (); +} + int gnu_history::do_where (void) const { @@ -587,6 +595,13 @@ instance->do_remove (n); } +void +command_history::clear (void) +{ + if (instance_ok ()) + instance->do_clear (); +} + int command_history::where (void) { @@ -807,6 +822,11 @@ { } +void +command_history::do_clear (void) +{ +} + int command_history::do_where (void) const {
rename from liboctave/cmd-hist.h rename to liboctave/util/cmd-hist.h --- a/liboctave/cmd-hist.h +++ b/liboctave/util/cmd-hist.h @@ -65,6 +65,8 @@ static void remove (int); + static void clear (void); + static int where (void); static int length (void); @@ -158,6 +160,8 @@ virtual void do_remove (int); + virtual void do_clear (void); + virtual int do_where (void) const; virtual int do_length (void) const;
rename from liboctave/data-conv.cc rename to liboctave/util/data-conv.cc --- a/liboctave/data-conv.cc +++ b/liboctave/util/data-conv.cc @@ -291,7 +291,7 @@ else { (*current_liboctave_error_handler) - ("invalid repeat count in `%s'", str.c_str ()); + ("invalid repeat count in '%s'", str.c_str ()); return; } @@ -364,7 +364,7 @@ else { (*current_liboctave_error_handler) - ("invalid repeat count in `%s'", str.c_str ()); + ("invalid repeat count in '%s'", str.c_str ()); return; } @@ -852,7 +852,7 @@ default: (*current_liboctave_error_handler) - ("impossible state reached in file `%s' at line %d", + ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__); break; } @@ -979,7 +979,7 @@ default: (*current_liboctave_error_handler) - ("impossible state reached in file `%s' at line %d", + ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__); break; } @@ -1002,7 +1002,7 @@ default: (*current_liboctave_error_handler) - ("impossible state reached in file `%s' at line %d", + ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__); break; }
rename from liboctave/glob-match.h rename to liboctave/util/glob-match.h --- a/liboctave/glob-match.h +++ b/liboctave/util/glob-match.h @@ -36,9 +36,9 @@ enum opts { - pathname = 1, // No wildcard can ever match `/'. + pathname = 1, // No wildcard can ever match '/'. noescape = 2, // Backslashes don't quote special chars. - period = 4 // Leading `.' is matched only explicitly. + period = 4 // Leading '.' is matched only explicitly. }; glob_match (const std::string& p,
rename from liboctave/kpse.cc rename to liboctave/util/kpse.cc --- a/liboctave/kpse.cc +++ b/liboctave/util/kpse.cc @@ -57,8 +57,8 @@ #ifdef __DJGPP__ #include <fcntl.h> /* for long filenames' stuff */ -#include <dir.h> /* for `getdisk' */ -#include <io.h> /* for `setmode' */ +#include <dir.h> /* for 'getdisk' */ +#include <io.h> /* for 'setmode' */ #endif } @@ -67,7 +67,7 @@ #define KPATHSEA 32 #endif -/* System dependencies that are figured out by `configure'. If we are +/* System dependencies that are figured out by 'configure'. If we are compiling standalone, we get our c-auto.h. Otherwise, the package containing us must provide this (unless it can somehow generate ours from c-auto.in). We use <...> instead of "..." so that the current @@ -111,7 +111,7 @@ #ifndef IS_DIR_SEP #define IS_DIR_SEP(ch) ((ch) == DIR_SEP) #endif -#ifndef IS_DEVICE_SEP /* No `devices' on, e.g., Unix. */ +#ifndef IS_DEVICE_SEP /* No 'devices' on, e.g., Unix. */ #define IS_DEVICE_SEP(ch) 0 #endif #ifndef NAME_BEGINS_WITH_DEVICE @@ -276,7 +276,7 @@ /* Define common sorts of messages. */ /* This should be called only after a system call fails. Don't exit - with status `errno', because that might be 256, which would mean + with status 'errno', because that might be 256, which would mean success (exit statuses are truncated to eight bits). */ #define FATAL_PERROR(str) \ do \ @@ -339,7 +339,7 @@ static string_vector kpse_db_search (const std::string& name, const std::string& path_elt, bool all); -#include <ctime> /* for `time' */ +#include <ctime> /* for 'time' */ static bool kpse_is_env_sep (char c) @@ -711,7 +711,7 @@ filename.c_str ()); /* And show them online, if debugging. We've already started - the debugging line in `search', where this is called, so + the debugging line in 'search', where this is called, so just print the filename here, don't use DEBUGF. */ if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) gnulib::fputs (filename.c_str (), stderr); @@ -768,7 +768,7 @@ string_vector ret_list; std::string found = kpse_readable_file (name); - /* Add `found' to the return list even if it's null; that tells + /* Add 'found' to the return list even if it's null; that tells the caller we didn't find anything. */ ret_list.append (found); @@ -830,8 +830,8 @@ (2b) no db exists; or (2c) no db's are relevant to this elt; or (3) MUST_EXIST && NAME was not in the db. - In (2*), `found' will be NULL. - In (3), `found' will be an empty list. */ + In (2*), 'found' will be NULL. + In (3), 'found' will be an empty list. */ if (allow_disk_search && found.empty ()) { @@ -912,7 +912,7 @@ /* Search PATH for the first NAME. */ -/* Call `kpse_expand' on NAME. If the result is an absolute or +/* Call 'kpse_expand' on NAME. If the result is an absolute or explicitly relative filename, check whether it is a readable (regular) file. @@ -940,9 +940,9 @@ } /* Search all elements of PATH for files named NAME. Not sure if it's - right to assert `must_exist' here, but it suffices now. */ - -/* Like `kpse_path_search' with MUST_EXIST true, but return a list of + right to assert 'must_exist' here, but it suffices now. */ + +/* Like 'kpse_path_search' with MUST_EXIST true, but return a list of all the filenames (or NULL if none), instead of taking the first. */ static string_vector @@ -1026,8 +1026,8 @@ (2c) no db's are relevant to this elt; or (3) MUST_EXIST && NAME was not in the db. - In (2*), `found' will be NULL. - In (3), `found' will be an empty list. */ + In (2*), 'found' will be NULL. + In (3), 'found' will be an empty list. */ if (allow_disk_search && found.empty ()) { @@ -1162,7 +1162,7 @@ /* Search each element of PATH for each element of NAMES and return a list containing everything found, in the order found. */ -/* Like `kpse_path_find_first_of' with MUST_EXIST true, but return a +/* Like 'kpse_path_find_first_of' with MUST_EXIST true, but return a list of all the filenames (or NULL if none), instead of taking the first. */ @@ -1192,7 +1192,7 @@ { expansion = name; - /* If a bare tilde, return the home directory or `.'. (Very + /* If a bare tilde, return the home directory or '.'. (Very unlikely that the directory name will do anyone any good, but ... */ } @@ -1203,7 +1203,7 @@ if (expansion.empty ()) expansion = "."; - /* If `~/', remove any trailing / or replace leading // in $HOME. + /* If '~/', remove any trailing / or replace leading // in $HOME. Should really check for doubled intermediate slashes, too. */ } else if (IS_DIR_SEP (name[1])) @@ -1226,7 +1226,7 @@ expansion = home + name.substr (c); - /* If `~user' or `~user/', look up user in the passwd database (but + /* If '~user' or '~user/', look up user in the passwd database (but OS/2 doesn't have this concept. */ } else @@ -1241,10 +1241,10 @@ std::string user = name.substr (1, c-1); /* We only need the cast here for (deficient) systems - which do not declare `getpwnam' in <pwd.h>. */ + which do not declare 'getpwnam' in <pwd.h>. */ octave_passwd p = octave_passwd::getpwnam (user); - /* If no such user, just use `.'. */ + /* If no such user, just use '.'. */ std::string home = p ? p.dir () : std::string ("."); if (home.empty ()) @@ -1356,11 +1356,11 @@ return ret; } -/* Do brace expansion and call `kpse_expand' on each element of the +/* Do brace expansion and call 'kpse_expand' on each element of the result; return the final expansion (always in fresh memory, even if - no expansions were done). We don't call `kpse_expand_default' + no expansions were done). We don't call 'kpse_expand_default' because there is a whole sequence of defaults to run through; see - `kpse_init_format'. */ + 'kpse_init_format'. */ static std::string kpse_brace_expand (const std::string& path) @@ -1394,8 +1394,8 @@ /* Expand all special constructs in a path, and include only the actually existing directories in the result. */ -/* Do brace expansion and call `kpse_expand' on each argument of the - result, then expand any `//' constructs. The final expansion (always +/* Do brace expansion and call 'kpse_expand' on each argument of the + result, then expand any '//' constructs. The final expansion (always in fresh memory) is a path of all the existing directories that match the pattern. */ @@ -1671,8 +1671,8 @@ (i+1 < text_len && (brace_whitespace (text[i+1]) || text[i+1] == '}')))) continue; - /* If this is being compiled as part of bash, ignore the `{' - in a `${}' construct */ + /* If this is being compiled as part of bash, ignore the '{' + in a '${}' construct */ if ((c != '{') || i == 0 || (text[i-1] != '$')) break; } @@ -1714,8 +1714,8 @@ string_vector suffix; /* For kpse_find_file to check for/append. */ }; -/* The sole variable of that type, indexed by `kpse_file_format_type'. - Initialized by calls to `kpse_find_file' for `kpse_init_format'. */ +/* The sole variable of that type, indexed by 'kpse_file_format_type'. + Initialized by calls to 'kpse_find_file' for 'kpse_init_format'. */ static kpse_format_info_type kpse_format_info; /* And EXPAND_DEFAULT calls kpse_expand_default on try_path and the @@ -1793,11 +1793,11 @@ component of FILENAME, we've matched. */ if (! matched && *path_elt == 0) { - /* Probably PATH_ELT ended with `vf' or some such, and FILENAME - ends with `vf/ptmr.vf'. In that case, we'll be at a + /* Probably PATH_ELT ended with 'vf' or some such, and FILENAME + ends with 'vf/ptmr.vf'. In that case, we'll be at a directory separator. On the other hand, if PATH_ELT ended - with a / (as in `vf/'), FILENAME being the same `vf/ptmr.vf', - we'll be at the `p'. Upshot: if we're at a dir separator in + with a / (as in 'vf/'), FILENAME being the same 'vf/ptmr.vf', + we'll be at the 'p'. Upshot: if we're at a dir separator in FILENAME, skip it. But if not, that's ok, as long as there are no more dir separators. */ @@ -1874,8 +1874,8 @@ return ret; /* When tex-glyph.c calls us looking for, e.g., dpi600/cmr10.pk, we - won't find it unless we change NAME to just `cmr10.pk' and append - `/dpi600' to PATH_ELT. We are justified in using a literal `/' + won't find it unless we change NAME to just 'cmr10.pk' and append + '/dpi600' to PATH_ELT. We are justified in using a literal '/' here, since that's what tex-glyph.c unconditionally uses in DPI_BITMAP_SPEC. But don't do anything if the / begins NAME; that should never happen. */ @@ -1889,7 +1889,7 @@ else path_elt = orig_path_elt; - /* Don't bother doing any lookups if this `path_elt' isn't covered by + /* Don't bother doing any lookups if this 'path_elt' isn't covered by any of database directories. We do this not so much because the extra couple of hash lookups matter -- they don't -- but rather because we want to return NULL in this case, so path_search can @@ -1917,7 +1917,7 @@ { std::string atry = aliases[i]; - /* We have an ls-R db. Look up `atry'. */ + /* We have an ls-R db. Look up 'atry'. */ string_vector db_dirs = hash_lookup (db, atry); /* For each filename found, see if it matches the path element. For @@ -1947,8 +1947,8 @@ { /* The hit in the DB doesn't exist in disk. Now try all its aliases. For example, suppose we have a - hierarchy on CD, thus `mf.bas', but ls-R contains - `mf.base'. Find it anyway. Could probably work + hierarchy on CD, thus 'mf.bas', but ls-R contains + 'mf.base'. Find it anyway. Could probably work around this with aliases, but this is pretty easy and shouldn't hurt. The upshot is that if one of the aliases actually exists, we use that. */ @@ -2228,8 +2228,8 @@ else { /* If we do have something to match, see if it exists. For - example, POST might be `pk/ljfour', and they might have a - directory `$TEXMF/fonts/pk/ljfour' that we should find. */ + example, POST might be 'pk/ljfour', and they might have a + directory '$TEXMF/fonts/pk/ljfour' that we should find. */ name += post; expand_elt (str_list_ptr, name, elt_length); name.resize (elt_length); @@ -2274,8 +2274,8 @@ else { /* If we do have something to match, see if it exists. For - example, POST might be `pk/ljfour', and they might have a - directory `$TEXMF/fonts/pk/ljfour' that we should find. */ + example, POST might be 'pk/ljfour', and they might have a + directory '$TEXMF/fonts/pk/ljfour' that we should find. */ name += post; expand_elt (str_list_ptr, name, elt_length); name.resize (elt_length); @@ -2283,7 +2283,7 @@ while ((e = gnulib::readdir (dir))) { - /* If it begins with a `.', never mind. (This allows ``hidden'' + /* If it begins with a '.', never mind. (This allows "hidden" directories that the algorithm won't find.) */ if (e->d_name[0] != '.') @@ -2326,7 +2326,7 @@ #endif } - /* Remove the directory entry we just checked from `name'. */ + /* Remove the directory entry we just checked from 'name'. */ name.resize (elt_length); } } @@ -2388,7 +2388,7 @@ current working directory. It's up to the caller to expand ELT. This is because this routine is - most likely only useful to be called from `kpse_path_search', which + most likely only useful to be called from 'kpse_path_search', which has already assumed expansion has been done. */ static str_llist_type * @@ -2493,20 +2493,20 @@ /* If we are the first unmoved element, nothing to relink. */ if (unmoved != mover) - { /* Remember `mover's current successor, so we can relink `mover's + { /* Remember 'mover's current successor, so we can relink 'mover's predecessor to it. */ str_llist_elt_type *before_mover; str_llist_elt_type *after_mover = STR_LLIST_NEXT (*mover); - /* Find `mover's predecessor. */ + /* Find 'mover's predecessor. */ for (before_mover = unmoved; STR_LLIST_NEXT (*before_mover) != mover; before_mover = STR_LLIST_NEXT (*before_mover)) ; - /* `before_mover' now links to `after_mover'. */ + /* 'before_mover' now links to 'after_mover'. */ STR_LLIST_NEXT (*before_mover) = after_mover; - /* Insert `mover' before `unmoved' and after `last_moved' (or at + /* Insert 'mover' before 'unmoved' and after 'last_moved' (or at the head of the list). */ STR_LLIST_NEXT (*mover) = unmoved; if (! last_moved) @@ -2544,8 +2544,8 @@ ? expansions[var] : false; } -/* Append the result of value of `var' to EXPANSION, where `var' begins - at START and ends at END. If `var' is not set, do not complain. +/* Append the result of value of 'var' to EXPANSION, where 'var' begins + at START and ends at END. If 'var' is not set, do not complain. This is a subroutine for the more complicated expansion function. */ static void @@ -2554,7 +2554,7 @@ if (expanding_p (var)) { (*current_liboctave_warning_handler) - ("kpathsea: variable `%s' references itself (eventually)", + ("kpathsea: variable '%s' references itself (eventually)", var.c_str ()); } else @@ -2604,7 +2604,7 @@ { i++; - /* Three cases: `$VAR', `${VAR}', `$<anything-else>'. */ + /* Three cases: '$VAR', '${VAR}', '$<anything-else>'. */ if (IS_VAR_CHAR (src[i])) { /* $V: collect name constituents, then expand. */ @@ -2645,7 +2645,7 @@ { /* $<something-else>: error. */ (*current_liboctave_warning_handler) - ("%s: Unrecognized variable construct `$%c'", + ("%s: Unrecognized variable construct '$%c'", src.c_str (), src[i]); /* Just ignore those chars and keep going. */
rename from liboctave/lo-cutils.c rename to liboctave/util/lo-cutils.c --- a/liboctave/lo-cutils.c +++ b/liboctave/util/lo-cutils.c @@ -79,7 +79,7 @@ return WAITPID (pid, status, options); } -static void +static inline void gripe_missing_wait_macro (const char *id, int status) { (*current_liboctave_warning_handler)
rename from liboctave/lo-utils.cc rename to liboctave/util/lo-utils.cc --- a/liboctave/lo-utils.cc +++ b/liboctave/util/lo-utils.cc @@ -106,7 +106,7 @@ // As far as I can see there's no way to distinguish between the // various errors; putenv doesn't have errno values. - if (putenv (new_item) < 0) + if (gnulib::putenv (new_item) < 0) (*current_liboctave_error_handler) ("putenv (%s) failed", new_item); }
new file mode 100644 --- /dev/null +++ b/liboctave/util/module.mk @@ -0,0 +1,88 @@ +EXTRA_DIST += \ + util/module.mk + +UTIL_INC = \ + util/base-list.h \ + util/byte-swap.h \ + util/caseless-str.h \ + util/cmd-edit.h \ + util/cmd-hist.h \ + util/data-conv.h \ + util/functor.h \ + util/glob-match.h \ + util/lo-array-gripes.h \ + util/lo-cutils.h \ + util/lo-ieee.h \ + util/lo-macros.h \ + util/lo-math.h \ + util/lo-traits.h \ + util/lo-utils.h \ + util/oct-alloc.h \ + util/oct-base64.h \ + util/oct-binmap.h \ + util/oct-cmplx.h \ + util/oct-glob.h \ + util/oct-inttypes.h \ + util/oct-locbuf.h \ + util/oct-md5.h \ + util/oct-mem.h \ + util/oct-mutex.h \ + util/oct-refcount.h \ + util/oct-rl-edit.h \ + util/oct-rl-hist.h \ + util/oct-shlib.h \ + util/oct-sort.h \ + util/oct-sparse.h \ + util/pathsearch.h \ + util/regexp.h \ + util/singleton-cleanup.h \ + util/sparse-sort.h \ + util/sparse-util.h \ + util/statdefs.h \ + util/str-vec.h \ + util/sun-utils.h + +UTIL_C_SRC = \ + util/f2c-main.c \ + util/lo-cieee.c \ + util/lo-cutils.c \ + util/oct-rl-edit.c \ + util/oct-rl-hist.c + +UTIL_SRC = \ + util/cmd-edit.cc \ + util/cmd-hist.cc \ + util/data-conv.cc \ + util/glob-match.cc \ + util/lo-array-gripes.cc \ + util/lo-ieee.cc \ + util/lo-utils.cc \ + util/oct-alloc.cc \ + util/oct-base64.cc \ + util/oct-glob.cc \ + util/oct-inttypes.cc \ + util/oct-locbuf.cc \ + util/oct-md5.cc \ + util/oct-mutex.cc \ + util/oct-shlib.cc \ + util/pathsearch.cc \ + util/regexp.cc \ + util/singleton-cleanup.cc \ + util/sparse-sort.cc \ + util/sparse-util.cc \ + util/str-vec.cc \ + $(UTIL_C_SRC) + +TEMPLATE_SRC += \ + util/oct-sort.cc + +OTHER_INC += \ + util/kpse.cc + +noinst_LTLIBRARIES += util/libutil.la + +util_libutil_la_SOURCES = $(UTIL_SRC) +util_libutil_la_CPPFLAGS = \ + $(liboctave_la_CPPFLAGS) \ + $(SPARSE_XCPPFLAGS) +
new file mode 100644 --- /dev/null +++ b/liboctave/util/oct-base64.cc @@ -0,0 +1,90 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <algorithm> + +#include <base64.h> + +#include "Array.h" +#include "oct-base64.h" + +bool +octave_base64_encode (const char *inc, const size_t inlen, char **out) +{ + bool ret = false; + + size_t outlen = base64_encode_alloc (inc, inlen, out); + + if (! *out) + { + if (outlen == 0 && inlen != 0) + (*current_liboctave_error_handler) + ("base64_encode: input array too large"); + else + (*current_liboctave_error_handler) + ("base64_encode: memory allocation error"); + } + else + ret = true; + + return ret; +} + +Array<double> +octave_base64_decode (const std::string& str) +{ + Array<double> retval; + + const char *inc = &(str[0]); + + char *out; + size_t outlen; + + bool ok = base64_decode_alloc (inc, str.length (), &out, &outlen); + + if (! ok) + (*current_liboctave_error_handler) + ("base64_decode: input was not valid base64"); + else if (! out) + (*current_liboctave_error_handler) + ("base64_decode: memory allocation error"); + else + { + if ((outlen % (sizeof (double) / sizeof (char))) != 0) + (*current_liboctave_error_handler) + ("base64_decode: incorrect input size"); + else + { + octave_idx_type len = (outlen * sizeof (char)) / sizeof (double); + retval.resize (dim_vector (1, len)); + double *dout = reinterpret_cast<double*> (out); + std::copy (dout, dout + len, retval.fortran_vec ()); + } + } + + return retval; +} +
new file mode 100644 --- /dev/null +++ b/liboctave/util/oct-base64.h @@ -0,0 +1,37 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_base64_h) +#define octave_base64_h 1 + +#include <string> + +template<class T> class Array; + +extern OCTAVE_API bool +octave_base64_encode (const char *inc, const size_t inlen, char **out); + +extern OCTAVE_API Array<double> +octave_base64_decode (const std::string& str); + +#endif +
rename from liboctave/oct-locbuf.h rename to liboctave/util/oct-locbuf.h --- a/liboctave/oct-locbuf.h +++ b/liboctave/util/oct-locbuf.h @@ -174,7 +174,7 @@ #define OCTAVE_LOCAL_BUFFER_MAX_STACK_SIZE 8192 // If we have automatic arrays, we use an automatic array if the size -// is small enough. To avoid possibly evaluating `size' multiple +// is small enough. To avoid possibly evaluating 'size' multiple // times, we first cache it. Note that we always construct both the // stack array and the octave_local_buffer object, but only one of // them will be nonempty.
rename from liboctave/oct-md5.cc rename to liboctave/util/oct-md5.cc --- a/liboctave/oct-md5.cc +++ b/liboctave/util/oct-md5.cc @@ -21,7 +21,7 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif #include <cstdio> @@ -78,7 +78,7 @@ (*current_liboctave_error_handler) ("internal error in md5_stream"); } else - (*current_liboctave_error_handler) ("unable to open file `%s' for reading", + (*current_liboctave_error_handler) ("unable to open file '%s' for reading", file.c_str ()); return retval;
rename from liboctave/oct-rl-hist.c rename to liboctave/util/oct-rl-hist.c --- a/liboctave/oct-rl-hist.c +++ b/liboctave/util/oct-rl-hist.c @@ -210,6 +210,12 @@ } } +void +octave_clear_history (void) +{ + clear_history (); +} + char * octave_history_goto_mark (int n) {
rename from liboctave/oct-rl-hist.h rename to liboctave/util/oct-rl-hist.h --- a/liboctave/oct-rl-hist.h +++ b/liboctave/util/oct-rl-hist.h @@ -66,6 +66,8 @@ extern void octave_remove_history (int); +extern void octave_clear_history (void); + extern char *octave_history_goto_mark (int n); extern char *octave_history_get (int n);
rename from liboctave/oct-shlib.cc rename to liboctave/util/oct-shlib.cc --- a/liboctave/oct-shlib.cc +++ b/liboctave/util/oct-shlib.cc @@ -272,7 +272,7 @@ if (! library) { using namespace std; - (*current_liboctave_error_handler) ("%s", strerror (errno)); + (*current_liboctave_error_handler) ("%s", gnulib::strerror (errno)); } }
rename from liboctave/regexp.cc rename to liboctave/util/regexp.cc --- a/liboctave/regexp.cc +++ b/liboctave/util/regexp.cc @@ -446,55 +446,80 @@ return retval; } +// Declare rep_token_t used in processing replacement string +typedef struct + { + size_t pos; + int num; + } rep_token_t; + + std::string regexp::replace (const std::string& buffer, const std::string& replacement) { std::string retval; + regexp::match_data rx_lst = match (buffer); + + size_t num_matches = rx_lst.size (); + + if (num_matches == 0) + { + retval = buffer; + return retval; + } + // Identify replacement tokens; build a vector of group numbers in // the replacement string so that we can quickly calculate the size // of the replacement. - int tokens = 0; - for (size_t i=1; i < replacement.size (); i++) + // FIXME: All code assumes that only 10 tokens ($0-$9) exist. + // $11 represents $1 followed by the character '1' rather than + // the eleventh capture buffer. + + std::string repstr = replacement; + std::vector<rep_token_t> tokens; + tokens.reserve (5); // Reserve memory for 5 pattern replacements + + for (size_t i=0; i < repstr.size (); i++) { - if (replacement[i-1]=='$' && isdigit (replacement[i])) + if (repstr[i] == '\\') { - tokens++; - i++; + if (i < repstr.size () - 1 && repstr[i+1] == '$') + { + repstr.erase (i,1); // erase backslash + i++; // skip over '$' + continue; + } + if (i < repstr.size () - 1 && repstr[i+1] == '\\') + { + repstr.erase (i,1); // erase 1st backslash + continue; + } } - } - std::vector<int> token (tokens); + else if (repstr[i] == '$') + { + if (i < repstr.size () - 1 && isdigit (repstr[i+1])) + { + rep_token_t tmp_token; - int kk = 0; - for (size_t i = 1; i < replacement.size (); i++) - { - if (replacement[i-1]=='$' && isdigit (replacement[i])) - { - token[kk++] = replacement[i]-'0'; - i++; + tmp_token.pos = i; + tmp_token.num = repstr[i+1]-'0'; + tokens.push_back (tmp_token); + } } } - regexp::match_data rx_lst = match (buffer); - - size_t sz = rx_lst.size (); + std::string rep; + int num_tokens = tokens.size (); - if (sz == 0) - { - retval = buffer; - return retval; - } - - std::string rep; - - if (tokens > 0) + if (num_tokens > 0) { // Determine replacement length - const size_t replen = replacement.size () - 2*tokens; + const size_t replen = repstr.size () - 2*num_tokens; int delta = 0; regexp::match_data::const_iterator p = rx_lst.begin (); - for (size_t i = 0; i < sz; i++) + for (size_t i = 0; i < num_matches; i++) { OCTAVE_QUIT; @@ -503,13 +528,13 @@ const Matrix pairs (p->token_extents ()); size_t pairlen = 0; - for (int j = 0; j < tokens; j++) + for (int j = 0; j < num_tokens; j++) { - if (token[j] == 0) + if (tokens[j].num == 0) pairlen += static_cast<size_t> (end - start) + 1; - else if (token[j] <= pairs.rows ()) - pairlen += static_cast<size_t> (pairs(token[j]-1,1) - - pairs(token[j]-1,0)) + 1; + else if (tokens[j].num <= pairs.rows ()) + pairlen += static_cast<size_t> (pairs(tokens[j].num-1,1) + - pairs(tokens[j].num-1,0)) + 1; } delta += (static_cast<int> (replen + pairlen) - static_cast<int> (end - start + 1)); @@ -520,7 +545,7 @@ rep.reserve (buffer.size () + delta); size_t from = 0; p = rx_lst.begin (); - for (size_t i = 0; i < sz; i++) + for (size_t i = 0; i < num_matches; i++) { OCTAVE_QUIT; @@ -531,51 +556,50 @@ rep.append (&buffer[from], static_cast<size_t> (start - 1) - from); from = static_cast<size_t> (end - 1) + 1; - for (size_t j = 1; j < replacement.size (); j++) + size_t cur_pos = 0; + + for (int j = 0; j < num_tokens; j++) { - if (replacement[j-1]=='$' && isdigit (replacement[j])) + rep.append (&repstr[cur_pos], (tokens[j].pos) - cur_pos); + cur_pos = tokens[j].pos+2; + + int k = tokens[j].num; + if (k == 0) { - int k = replacement[j]-'0'; - if (k == 0) - { - // replace with entire match - rep.append (&buffer[static_cast<size_t> (end - 1)], - static_cast<size_t> (end - start) + 1); - } - else if (k <= pairs.rows ()) - { - // replace with group capture - rep.append (&buffer[static_cast<size_t> (pairs(k-1,0)-1)], - static_cast<size_t> (pairs(k-1,1) - - pairs(k-1,0)) + 1); - } - else - { - // replace with nothing - } - j++; + // replace with entire match + rep.append (&buffer[static_cast<size_t> (end - 1)], + static_cast<size_t> (end - start) + 1); + } + else if (k <= pairs.rows ()) + { + // replace with group capture + rep.append (&buffer[static_cast<size_t> (pairs(k-1,0)-1)], + static_cast<size_t> (pairs(k-1,1) + - pairs(k-1,0)) + 1); } else - rep.append (1, replacement[j-1]); + { + // replace with nothing + } + } + if (cur_pos < repstr.size ()) + rep.append (&repstr[cur_pos], repstr.size () - cur_pos); - if (j+1 == replacement.size ()) - rep.append (1, replacement[j]); - } p++; } rep.append (&buffer[from], buffer.size () - from); } else { - // Determine replacement length - const size_t replen = replacement.size (); + // Determine repstr length + const size_t replen = repstr.size (); int delta = 0; regexp::match_data::const_iterator p = rx_lst.begin (); - for (size_t i = 0; i < sz; i++) + for (size_t i = 0; i < num_matches; i++) { OCTAVE_QUIT; delta += static_cast<int> (replen) - - static_cast<int> (p->end () - p->start () + 1); + - static_cast<int> (p->end () - p->start () + 1); p++; } @@ -583,13 +607,13 @@ rep.reserve (buffer.size () + delta); size_t from = 0; p = rx_lst.begin (); - for (size_t i = 0; i < sz; i++) + for (size_t i = 0; i < num_matches; i++) { OCTAVE_QUIT; rep.append (&buffer[from], static_cast<size_t> (p->start () - 1) - from); from = static_cast<size_t> (p->end () - 1) + 1; - rep.append (replacement); + rep.append (repstr); p++; } rep.append (&buffer[from], buffer.size () - from);
rename from liboctave/sparse-util.cc rename to liboctave/util/sparse-util.cc --- a/liboctave/sparse-util.cc +++ b/liboctave/util/sparse-util.cc @@ -32,6 +32,9 @@ #include "sparse-util.h" // FIXME this overload is here due to API change in SuiteSparse (3.1 -> 3.2) + +#ifdef HAVE_CHOLMOD + void SparseCholError (int status, char *file, int line, char *message) { @@ -41,6 +44,7 @@ void SparseCholError (int status, const char *file, int line, const char *message) { + // Ignore CHOLMOD_NOT_POSDEF, since we handle that in Fchol as an // error or exit status. if (status != CHOLMOD_NOT_POSDEF) @@ -63,6 +67,7 @@ return ret; } +#endif //HAVE_CHOLMOD bool sparse_indices_ok (octave_idx_type *r, octave_idx_type *c,
rename from liboctave/sparse-util.h rename to liboctave/util/sparse-util.h --- a/liboctave/sparse-util.h +++ b/liboctave/util/sparse-util.h @@ -24,6 +24,8 @@ #if !defined (octave_sparse_util_h) #define octave_sparse_util_h 1 +#ifdef HAVE_CHOLMOD + // FIXME this overload is here due to API change in SuiteSparse (3.1 -> 3.2) extern OCTAVE_API void SparseCholError (int status, char *file, int line, char *message); @@ -31,6 +33,8 @@ int line, const char *message); extern OCTAVE_API int SparseCholPrint (const char *fmt, ...); +#endif //HAVE_CHOLMOD + extern OCTAVE_API bool sparse_indices_ok (octave_idx_type *r, octave_idx_type *c, octave_idx_type nrows, octave_idx_type ncols,
--- a/m4/acinclude.m4 +++ b/m4/acinclude.m4 @@ -74,21 +74,21 @@ AC_MSG_CHECKING([whether ${CC-cc} accepts $1]) AC_CACHE_VAL([octave_cv_cc_flag_$ac_safe], [AC_LANG_PUSH(C) - XCFLAGS="$CFLAGS" + ac_octave_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [eval "octave_cv_cc_flag_$ac_safe=yes"], [eval "octave_cv_cc_flag_$ac_safe=no"]) - CFLAGS="$XCFLAGS" + CFLAGS="$ac_octave_save_CFLAGS" AC_LANG_POP(C) ]) if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ifelse([$2], , [CFLAGS="$CFLAGS $1" AC_MSG_RESULT([adding $1 to CFLAGS])], [$2]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ifelse([$3], , , [$3]) fi ]) @@ -143,6 +143,35 @@ fi ]) dnl +dnl Check whether Qscintilla FindFirst function is old (16 inputs) or +dnl new (17 inputs). +dnl FIXME: This test uses a version number. It potentially could +dnl be re-written to actually call the function, but is it worth it? +dnl +AC_DEFUN([OCTAVE_CHECK_FUNC_FINDFIRST_MODERN], [ + AC_CACHE_CHECK([whether Qscintilla FindFirst uses 17 input arguments], + [octave_cv_func_findfirst_modern], + [AC_LANG_PUSH(C++) + ac_octave_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="-I$QT_INCDIR -I$QT_INCDIR/Qt $CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <Qsci/qsciglobal.h> + ]], [[ + #if QSCINTILLA_VERSION < 0x020600 + #error Old FindFirst function found. + #endif + ]])], + octave_cv_func_findfirst_modern=yes, + octave_cv_func_findfirst_modern=no) + CPPFLAGS="$ac_octave_save_CPPFLAGS" + AC_LANG_POP(C++) + ]) + if test $octave_cv_func_findfirst_modern = yes; then + AC_DEFINE(HAVE_FINDFIRST_MODERN, 1, + [Define to 1 if Qscintilla FindFirst uses modern form with 17 inputs.]) + fi +]) +dnl dnl Check if Fortran compiler has the intrinsic function ISNAN. dnl AC_DEFUN([OCTAVE_CHECK_FUNC_FORTRAN_ISNAN], [ @@ -187,12 +216,40 @@ octave_cv_func_glutesscallback_threedots=no) AC_LANG_POP(C++) ]) - if test $octave_cv_func_glutesscallback_threedots = "yes"; then + if test $octave_cv_func_glutesscallback_threedots = yes; then AC_DEFINE(HAVE_GLUTESSCALLBACK_THREEDOTS, 1, [Define to 1 if gluTessCallback is called with (...).]) fi ]) dnl +dnl Check whether Qscintilla SetPlaceholderText function exists. +dnl FIXME: This test uses a version number. It potentially could +dnl be re-written to actually call the function, but is it worth it? +dnl +AC_DEFUN([OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT], [ + AC_CACHE_CHECK([whether Qt has SetPlaceholderText function], + [octave_cv_func_setplaceholdertext], + [AC_LANG_PUSH(C++) + ac_octave_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="-I$QT_INCDIR $CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <Qt/qglobal.h> + ]], [[ + #if QT_VERSION < 0x040700 + #error No SetPlacholderText function available. + #endif + ]])], + octave_cv_func_setplaceholdertext=yes, + octave_cv_func_setplaceholdertext=no) + CPPFLAGS="$ac_octave_save_CPPFLAGS" + AC_LANG_POP(C++) + ]) + if test $octave_cv_func_setplaceholdertext = yes; then + AC_DEFINE(HAVE_SETPLACEHOLDERTEXT, 1, + [Define to 1 if you have the Qt SetPlaceholderText function.]) + fi +]) +dnl dnl Check whether HDF5 library has version 1.6 API functions. dnl AC_DEFUN([OCTAVE_CHECK_HDF5_HAS_VER_16_API], [ @@ -206,7 +263,7 @@ octave_cv_hdf5_has_ver_16_api=yes, octave_cv_hdf5_has_ver_16_api=no) ]) - if test "$octave_cv_hdf5_has_ver_16_api" != "yes"; then + if test $octave_cv_hdf5_has_ver_16_api != yes; then AC_DEFINE(HAVE_HDF5_18, 1, [Define to 1 if >=HDF5-1.8 is available.]) fi ]) @@ -255,35 +312,36 @@ m4_set_add([summary_warning_list], [warn_$1]) if test -n "$m4_toupper([$1])_LIBS"; then - octave_check_lib_save_CPPFLAGS="$CPPFLAGS" + ac_octave_save_CPPFLAGS="$CPPFLAGS" + ac_octave_save_LDFLAGS="$LDFLAGS" + ac_octave_save_LIBS="$LIBS" CPPFLAGS="$m4_toupper([$1])_CPPFLAGS $CPPFLAGS" + LDFLAGS="$m4_toupper([$1])_LDFLAGS $LDFLAGS" + LIBS="$m4_toupper([$1])_LIBS $LIBS" m4_ifnblank([$6], [AC_LANG_PUSH($6)]) - octave_$1_check_for_lib=false - m4_ifblank([$4], [octave_$1_check_for_lib=true], - [AC_CHECK_HEADERS($4, [octave_$1_check_for_lib=true; break])]) - if $octave_$1_check_for_lib; then - octave_check_lib_save_LDFLAGS="$LDFLAGS" - LDFLAGS="$m4_toupper([$1])_LDFLAGS $LDFLAGS" - octave_check_lib_save_LIBS="$LIBS" - LIBS="$m4_toupper([$1])_LIBS $LIBS" - octave_$1_ok=no - AC_MSG_CHECKING([for $5 in $m4_toupper([$1])_LIBS]) - AC_LINK_IFELSE([AC_LANG_CALL([], [$5])], - [octave_$1_ok=yes]) - AC_MSG_RESULT([$octave_$1_ok]) - if test $octave_$1_ok = yes; then + ac_octave_$1_check_for_lib=false + m4_ifblank([$4], [ac_octave_$1_check_for_lib=true], + [AC_CHECK_HEADERS([$4], [ac_octave_$1_check_for_lib=true; break])]) + if $ac_octave_$1_check_for_lib; then + AC_CACHE_CHECK([for $5 in $m4_toupper([$1])_LIBS], + [octave_cv_lib_$1], + [AC_LINK_IFELSE([AC_LANG_CALL([], [$5])], + [octave_cv_lib_$1=yes], [octave_cv_lib_$1=no]) + ]) + if test "$octave_cv_lib_$1" = yes; then m4_ifblank([$8], [ warn_$1= AC_DEFINE([HAVE_]m4_toupper([$1]), 1, [Define to 1 if $2 is available.]) [TEXINFO_]m4_toupper([$1])="@set [HAVE_]m4_toupper([$1])"], [$8]) fi - LIBS="$octave_check_lib_save_LIBS" - LDFLAGS="$octave_check_lib_save_LDFLAGS" fi m4_ifnblank([$6], [AC_LANG_POP($6)]) - CPPFLAGS="$octave_check_lib_save_CPPFLAGS" + CPPFLAGS="$ac_octave_save_CPPFLAGS" + LDFLAGS="$ac_octave_save_LDFLAGS" + LIBS="$ac_octave_save_LIBS" fi + AC_SUBST(m4_toupper([$1])_LIBS) AC_SUBST([TEXINFO_]m4_toupper([$1])) if test -n "$warn_$1"; then @@ -300,10 +358,10 @@ dnl allocated arrays in Fortran does not? dnl AC_DEFUN([OCTAVE_CHECK_LIB_ARPACK_OK], [ - AC_LANG_PUSH(C++) AC_CACHE_CHECK([whether the arpack library works], [octave_cv_lib_arpack_ok], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + [AC_LANG_PUSH(C++) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ // External functions from ARPACK library extern "C" int F77_FUNC (dnaupd, DNAUPD) (int&, const char *, const int&, const char *, @@ -436,12 +494,14 @@ octave_cv_lib_arpack_ok=yes, octave_cv_lib_arpack_ok=no, octave_cv_lib_arpack_ok=yes) + AC_LANG_POP(C++) ]) - AC_LANG_POP(C++) - if test "$octave_cv_lib_arpack_ok" = "yes"; then + if test $octave_cv_lib_arpack_ok = yes; then $1 + : else $2 + : fi ]) dnl @@ -475,7 +535,7 @@ LIBS="$save_LIBS" ]) ]) - if test "$octave_cv_lib_hdf5_dll" = yes; then + if test $octave_cv_lib_hdf5_dll = yes; then AC_DEFINE(_HDF5USEDLL_, 1, [Define to 1 if using HDF5 dll (Win32).]) fi ]) @@ -500,7 +560,7 @@ ]], have_framework_opengl=yes, have_framework_opengl=no) - if test $have_framework_opengl = "yes"; then + if test $have_framework_opengl = yes; then AC_DEFINE(HAVE_FRAMEWORK_OPENGL, 1, [Define to 1 if framework OPENGL is available.]) OPENGL_LIBS="-Wl,-framework -Wl,OpenGL" @@ -509,7 +569,7 @@ else case $canonical_host_type in *-*-mingw32* | *-*-msdosmsvc) - AC_CHECK_HEADERS(windows.h) + AC_CHECK_HEADERS([windows.h]) ;; esac have_opengl_incs=no @@ -527,7 +587,7 @@ #endif ]) - if test "$have_opengl_incs" = "yes"; then + if test "$have_opengl_incs" = yes; then case $canonical_host_type in *-*-mingw32* | *-*-msdosmsvc) save_LIBS="$LIBS" @@ -548,14 +608,14 @@ LIBS="$save_LIBS" if test "x$OPENGL_LIBS" != "x"; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi ;; *) ## Non-Mac, Non-Windows systems use this check - AC_CHECK_LIB(GL, [glEnable], [OPENGL_LIBS="-lGL -lGLU"]) + AC_CHECK_LIB([GL], [glEnable], [OPENGL_LIBS="-lGL -lGLU"]) ;; esac fi @@ -611,20 +671,53 @@ octave_cv_lib_qhull_ok=no, octave_cv_lib_qhull_ok=yes) ]) - if test "$octave_cv_lib_qhull_ok" = "yes"; then + if test $octave_cv_lib_qhull_ok = yes; then $1 + : else $2 + : fi ]) dnl +dnl Find a suitable termlib to use. +dnl +AC_DEFUN([OCTAVE_CHECK_LIB_TERMLIB], [ + TERM_LIBS= + ac_octave_save_LIBS="$LIBS" + AC_SEARCH_LIBS([tputs], + [ncurses curses termcap terminfo termlib], + [], []) + LIBS="$ac_octave_save_LIBS" + case "$ac_cv_search_tputs" in + -l*) + TERM_LIBS="$ac_cv_search_tputs" + ;; + no) + warn_termlibs="I couldn't find -ltermcap, -lterminfo, -lncurses, -lcurses, or -ltermlib!" + AC_MSG_WARN([$warn_termlibs]) + ;; + esac + +dnl Old code (9/9/2012). Delete when new code is definitely proven. +dnl +dnl for _termlib in ncurses curses termcap terminfo termlib; do +dnl AC_CHECK_LIB([${_termlib}], [tputs], [ +dnl TERM_LIBS="-l${termlib}" +dnl octave_cv_lib_found_termlib=yes +dnl break]) +dnl done + + AC_SUBST(TERM_LIBS) +]) +dnl dnl Check for support of OpenMP with a given compiler flag. dnl If found define HAVE_OPENMP and add the compile flag dnl to CFLAGS and CXXFLAGS. dnl AC_DEFUN([OCTAVE_CHECK_OPENMP], [ AC_MSG_CHECKING([for support of OpenMP]) - XCFLAGS="$CFLAGS" + ac_octave_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_CACHE_VAL([octave_cv_check_openmp], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -641,11 +734,11 @@ octave_cv_openmp=yes, octave_cv_openmmp=no, octave_cv_openmp=no) ]) AC_MSG_RESULT([$octave_cv_openmp]) - if test "$octave_cv_openmp" = yes; then + if test $octave_cv_openmp = yes; then AC_DEFINE(HAVE_OPENMP, 1, [Define to 1 if compiler supports OpenMP.]) CXXFLAGS="$CXXFLAGS $1" else - CFLAGS="$XCFLAGS" + CFLAGS="$ac_octave_save_CFLAGS" fi ]) dnl @@ -688,7 +781,7 @@ ]])], octave_cv_lib_qhull_version=yes, octave_cv_lib_qhull_version=no) ]) - if test "$octave_cv_lib_qhull_version" = no; then + if test $octave_cv_lib_qhull_version = no; then AC_DEFINE(NEED_QHULL_VERSION, 1, [Define to 1 if the Qhull library needs a qh_version variable defined.]) fi @@ -699,7 +792,7 @@ AC_DEFUN([OCTAVE_CHECK_SIZEOF_FORTRAN_INTEGER], [ AC_CACHE_CHECK([whether $F77 generates correct size integers], [octave_cv_sizeof_fortran_integer], - [octave_fintsize_save_FFLAGS="$FFLAGS" + [ac_octave_save_FFLAGS="$FFLAGS" FFLAGS="$FFLAGS $F77_INTEGER_8_FLAG" AC_LANG_PUSH(Fortran 77) AC_COMPILE_IFELSE( @@ -713,7 +806,7 @@ end ]], [mv conftest.$ac_objext fintsize.$ac_objext - octave_fintsize_save_LIBS="$LIBS" + ac_octave_save_LIBS="$LIBS" LIBS="fintsize.$ac_objext $[]_AC_LANG_PREFIX[]LIBS" AC_LANG_PUSH(C) AC_RUN_IFELSE([AC_LANG_PROGRAM([[ @@ -739,13 +832,13 @@ octave_cv_sizeof_fortran_integer=no, octave_cv_sizeof_fortran_integer=yes) AC_LANG_POP(C) - LIBS="$octave_fintsize_save_LIBS" + LIBS="$ac_octave_save_LIBS" rm -f conftest.$ac_objext fintsize.$ac_objext], [rm -f conftest.$ac_objext AC_MSG_FAILURE([cannot compile a simple Fortran program]) octave_cv_sizeof_fortran_integer=no]) AC_LANG_POP(Fortran 77) - FFLAGS="$octave_fintsize_save_FFLAGS" + FFLAGS="$ac_octave_save_FFLAGS" ]) ]) dnl @@ -810,7 +903,7 @@ octave_cv_cxx_broken_reinterpret_cast=yes) AC_LANG_POP(C++) ]) - if test $octave_cv_cxx_broken_reinterpret_cast = yes ; then + if test $octave_cv_cxx_broken_reinterpret_cast = yes; then AC_DEFINE(CXX_BROKEN_REINTERPRET_CAST, 1, [Define to 1 if C++ reinterpret_cast fails for function pointers.]) fi @@ -894,21 +987,21 @@ AC_MSG_CHECKING([whether ${CXX-g++} accepts $1]) AC_CACHE_VAL([octave_cv_cxx_flag_$ac_safe], [AC_LANG_PUSH(C++) - XCXXFLAGS="$CXXFLAGS" + ac_octave_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $1" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], eval "octave_cv_cxx_flag_$ac_safe=yes", eval "octave_cv_cxx_flag_$ac_safe=no") - CXXFLAGS="$XCXXFLAGS" + CXXFLAGS="$ac_octave_save_CXXFLAGS" AC_LANG_POP(C++) ]) if eval "test \"`echo '$octave_cv_cxx_flag_'$ac_safe`\" = yes"; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ifelse([$2], , [CXXFLAGS="$CXXFLAGS $1" AC_MSG_RESULT([adding $1 to CXXFLAGS])], [$2]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ifelse([$3], , , [$3]) fi ]) @@ -1017,24 +1110,26 @@ AC_DEFUN([OCTAVE_ENABLE_READLINE], [ USE_READLINE=true READLINE_LIBS= - AC_ARG_ENABLE(readline, - [AS_HELP_STRING([--enable-readline], - [use readline library (default is yes)])], + AC_ARG_ENABLE([readline], + [AS_HELP_STRING([--disable-readline], + [use readline library])], [if test "$enableval" = no; then USE_READLINE=false warn_readline="command editing and history features require GNU Readline" fi]) if $USE_READLINE; then - save_LIBS="$LIBS" + dnl RHEL 5 and older systems require termlib set before enabling readline + AC_REQUIRE([OCTAVE_CHECK_LIB_TERMLIB]) + ac_octave_save_LIBS="$LIBS" LIBS="$TERM_LIBS" - AC_CHECK_LIB(readline, rl_set_keyboard_input_timeout, + AC_CHECK_LIB([readline], [rl_set_keyboard_input_timeout], [READLINE_LIBS="-lreadline" AC_DEFINE(USE_READLINE, 1, [Define to 1 to use the readline library.]) ], [AC_MSG_WARN([I need GNU Readline 4.2 or later]) AC_MSG_ERROR([this is fatal unless you specify --disable-readline]) ]) - LIBS="$save_LIBS" + LIBS="$ac_octave_save_LIBS" fi AC_SUBST(READLINE_LIBS) ]) @@ -1047,23 +1142,23 @@ AC_DEFUN([OCTAVE_F77_FLAG], [ ac_safe=`echo "$1" | sed 'y%./+-:=%__p___%'` AC_MSG_CHECKING([whether ${F77-g77} accepts $1]) - AC_CACHE_VAL(octave_cv_f77_flag_$ac_safe, [ + AC_CACHE_VAL([octave_cv_f77_flag_$ac_safe], [ AC_LANG_PUSH(Fortran 77) - XFFLAGS="$FFLAGS" + ac_octave_save_FFLAGS="$FFLAGS" FFLAGS="$FFLAGS $1" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], eval "octave_cv_f77_flag_$ac_safe=yes", eval "octave_cv_f77_flag_$ac_safe=no") - FFLAGS="$XFFLAGS" + FFLAGS="$ac_octave_save_FFLAGS" AC_LANG_POP(Fortran 77) ]) if eval "test \"`echo '$octave_cv_f77_flag_'$ac_safe`\" = yes"; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ifelse([$2], , [FFLAGS="$FFLAGS $1" AC_MSG_RESULT([adding $1 to FFLAGS])], [$2]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ifelse([$3], , , [$3]) fi ]) @@ -1151,29 +1246,30 @@ AC_DEFUN([OCTAVE_HAVE_FRAMEWORK], [ AC_MSG_CHECKING([whether ${LD-ld} accepts -framework $1]) AC_CACHE_VAL([octave_cv_framework_$1], - [XLDFLAGS="$LDFLAGS" + [ac_octave_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -framework $1" AC_LANG_PUSH(C++) AC_LINK_IFELSE([AC_LANG_PROGRAM([$2], [$3])], eval "octave_cv_framework_$1=yes", eval "octave_cv_framework_$1=no") AC_LANG_POP(C++) - LDFLAGS="$XLDFLAGS" + LDFLAGS="$ac_octave_save_LDFLAGS" ]) - if test "$octave_cv_framework_$1" = "yes"; then - AC_MSG_RESULT(yes) + if test "$octave_cv_framework_$1" = yes; then + AC_MSG_RESULT([yes]) AC_ARG_WITH(framework-m4_tolower($1), [AS_HELP_STRING([--without-framework-m4_tolower($1)], [don't use framework $1])], with_have_framework=$withval, with_have_framework=yes) - if test "$with_have_framework" = "yes"; then + if test "$with_have_framework" = yes; then [$4] + : else AC_MSG_NOTICE([framework rejected by --without-framework-m4_tolower($1)]) [$5] fi else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) [$5] fi ]) @@ -1221,7 +1317,7 @@ else AC_MSG_RESULT([$octave_cv_ieee754_data_format]) fi - if test "$octave_cv_ieee754_data_format" = yes; then + if test $octave_cv_ieee754_data_format = yes; then AC_DEFINE(HAVE_IEEE754_DATA_FORMAT, 1, [Define to 1 if your system uses IEEE 754 data format.]) else @@ -1277,7 +1373,7 @@ dnl dnl Find find program. dnl -# Prefer GNU find if found. +## Prefer GNU find if found. AN_MAKEVAR([FIND], [OCTAVE_PROG_FIND]) AN_PROGRAM([gfind], [OCTAVE_PROG_FIND]) AN_PROGRAM([find], [OCTAVE_PROG_FIND]) @@ -1318,13 +1414,13 @@ AC_DEFUN([OCTAVE_PROG_GHOSTSCRIPT], [ case "$canonical_host_type" in *-*-mingw* | *-*-msdosmsvc) - gs_names="gswin32c gs mgs" + ac_octave_gs_names="gswin32c gs mgs" ;; *) - gs_names="gs" + ac_octave_gs_names="gs" ;; esac - AC_CHECK_PROGS(GHOSTSCRIPT, [$gs_names]) + AC_CHECK_PROGS(GHOSTSCRIPT, [$ac_octave_gs_names]) if test -z "$GHOSTSCRIPT"; then GHOSTSCRIPT='$(top_srcdir)/build-aux/missing gs' warn_ghostscript=" @@ -1341,13 +1437,13 @@ dnl Check for gnuplot. dnl AC_DEFUN([OCTAVE_PROG_GNUPLOT], [ - gp_names="gnuplot" - gp_default="gnuplot" + ac_octave_gp_names="gnuplot" + ac_octave_gp_default="gnuplot" if test "$cross_compiling" = yes; then - GNUPLOT="$gp_default" + GNUPLOT="$ac_octave_gp_default" AC_MSG_RESULT([assuming $GNUPLOT exists on $canonical_host_type host]) else - AC_CHECK_PROGS(GNUPLOT, [$gp_names]) + AC_CHECK_PROGS(GNUPLOT, [$ac_octave_gp_names]) if test -z "$GNUPLOT"; then GNUPLOT="$gp_default" warn_gnuplot=" @@ -1398,14 +1494,14 @@ AC_MSG_RESULT([assuming $DEFAULT_PAGER exists on $canonical_host_type host]) AC_SUBST(DEFAULT_PAGER) else - octave_possible_pagers="less more page pg" + ac_octave_possible_pagers="less more page pg" case "$canonical_host_type" in *-*-cygwin* | *-*-mingw32* | *-*-msdosmsvc) - octave_possible_pagers="$octave_possible_pagers more.com" + ac_octave_possible_pagers="$ac_octave_possible_pagers more.com" ;; esac - AC_CHECK_PROGS(DEFAULT_PAGER, $octave_possible_pagers, []) + AC_CHECK_PROGS(DEFAULT_PAGER, [$ac_octave_possible_pagers], []) if test -z "$DEFAULT_PAGER"; then warn_less="I couldn't find \`less', \`more', \`page', or \`pg'" OCTAVE_CONFIGURE_WARNING([warn_less]) @@ -1506,6 +1602,7 @@ " OCTAVE_CONFIGURE_WARNING([warn_texi2dvi]) fi + TEXI2DVI="$TEXI2DVI"' --build-dir=t2d_cache' AC_SUBST(TEXI2DVI) ]) dnl @@ -1515,15 +1612,15 @@ AC_REQUIRE([OCTAVE_PROG_TEXI2DVI]) AC_CHECK_PROG(TEXI2PDF, texi2pdf, texi2pdf, []) if test -z "$TEXI2PDF"; then - missing=true; + ac_octave_missing=true; if test -n "$TEXI2DVI"; then TEXI2PDF="$TEXI2DVI --pdf" - missing=false; + ac_octave_missing=false; fi else - missing=false; + ac_octave_missing=false; fi - if $missing; then + if $ac_octave_missing; then TEXI2PDF='$(top_srcdir)/build-aux/missing texi2pdf' warn_texi2pdf=" @@ -1532,6 +1629,7 @@ " OCTAVE_CONFIGURE_WARNING([warn_texi2pdf]) fi + TEXI2PDF="$TEXI2PDF"' --build-dir=t2d_cache' AC_SUBST(TEXI2PDF) ]) dnl @@ -1544,15 +1642,45 @@ AC_SUBST($1) ]) dnl +dnl Check whether SuiteSparse_time is required by UMFPACK. +dnl UMFPACK >= 4 requires linking in another library for SuiteSparse_time. +dnl +dnl Macro assumes that the check for umfpack has already been performed. +dnl +AC_DEFUN([OCTAVE_UMFPACK_NEED_SUITESPARSE_TIME], [ + AC_CACHE_CHECK([whether UMFPACK needs SuiteSparse_time function], + [octave_cv_umfpack_need_suitesparse_time], + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #if defined (HAVE_SUITESPARSE_UMFPACK_H) + # include <suitesparse/umfpack.h> + #elif defined (HAVE_UFSPARSE_UMFPACK_H) + # include <ufsparse/umfpack.h> + #elif defined (HAVE_UMFPACK_UMFPACK_H) + # include <umfpack/umfpack.h> + #elif defined (HAVE_UMFPACK_H) + # include <umfpack.h> + #endif + ]], [[ + double stats [2]; + umfpack_tic (stats); + ]])], + octave_cv_umfpack_need_suitesparse_time=no, + octave_cv_umfpack_need_suitesparse_time=yes) + AC_LANG_POP(C) + ]) +]) +dnl dnl Check for UMFPACK separately split complex matrix and RHS. dnl dnl Macro assumes that the check for umfpack has already been performed. dnl AC_DEFUN([OCTAVE_UMFPACK_SEPARATE_SPLIT], [ AC_MSG_CHECKING([for UMFPACK separate complex matrix and rhs split]) - AC_CACHE_VAL(octave_cv_umfpack_separate_split, + AC_CACHE_VAL([octave_cv_umfpack_separate_split], [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <stdlib.h> + #include <math.h> #if defined (HAVE_SUITESPARSE_UMFPACK_H) # include <suitesparse/umfpack.h> #elif defined (HAVE_UFSPARSE_UMFPACK_H) @@ -1582,7 +1710,7 @@ Numeric, null, null) ; umfpack_zi_free_numeric (&Numeric) ; for (i = 0; i < n; i++, x+=2) - if (fabs(*x - i - 1.) > 1.e-13) + if (fabs (*x - i - 1.) > 1.e-13) return (1); return (0) ; } @@ -1596,7 +1724,7 @@ else AC_MSG_RESULT([$octave_cv_umfpack_separate_split]) fi - if test "$octave_cv_umfpack_separate_split" = yes; then + if test $octave_cv_umfpack_separate_split = yes; then AC_DEFINE(UMFPACK_SEPARATE_SPLIT, 1, [Define to 1 if the UMFPACK Complex solver allows matrix and RHS to be split independently.]) fi @@ -1612,7 +1740,7 @@ [octave_cv_header_require_tr1_namespace], [AC_LANG_PUSH(C++) octave_cv_header_require_tr1_namespace=no - if test "$ac_cv_header_unordered_map" = "yes"; then + if test $ac_cv_header_unordered_map = yes; then ## Have <unordered_map>, but still have to check whether ## tr1 namespace is required (like MSVC, for instance). AC_COMPILE_IFELSE( @@ -1623,12 +1751,12 @@ ]])], octave_cv_header_require_tr1_namespace=no, octave_cv_header_require_tr1_namespace=yes) - elif test "$ac_cv_header_tr1_unordered_map" = "yes"; then + elif test $ac_cv_header_tr1_unordered_map = yes; then octave_cv_header_require_tr1_namespace=yes fi AC_LANG_POP(C++) ]) - if test "$octave_cv_header_require_tr1_namespace" = "yes"; then + if test $octave_cv_header_require_tr1_namespace = yes; then AC_DEFINE(USE_UNORDERED_MAP_WITH_TR1, 1, [Define to 1 if unordered_map requires the use of tr1 namespace.]) fi @@ -1837,164 +1965,3 @@ ############################################################################## -############################################################################## - -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# -# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. -# -# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# 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. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi - -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# -# Similar to PKG_CHECK_MODULES, make sure that the first instance of -# this or PKG_CHECK_MODULES is called, or make sure to call -# PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_ifval([$2], [$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$PKG_CONFIG"; then - if test -n "$$1"; then - pkg_cv_[]$1="$$1" - else - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - fi -else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - ifelse([$4], , [AC_MSG_ERROR(dnl -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT -])], - [AC_MSG_RESULT([no]) - $4]) -elif test $pkg_failed = untried; then - ifelse([$4], , [AC_MSG_FAILURE(dnl -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see <http://pkg-config.freedesktop.org/>.])], - [$4]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - ifelse([$3], , :, [$3]) -fi[]dnl -])# PKG_CHECK_MODULES -dnl end of pkg.m4 -
--- a/m4/module.mk +++ b/m4/module.mk @@ -10,4 +10,5 @@ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ - m4/lt~obsolete.m4 + m4/lt~obsolete.m4 \ + m4/pkg.m4
new file mode 100644 --- /dev/null +++ b/m4/pkg.m4 @@ -0,0 +1,157 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [AC_MSG_RESULT([no]) + $4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES
--- a/run-octave.in +++ b/run-octave.in @@ -47,6 +47,7 @@ LOADPATH="$d1_path:$d2_path:$d3_path" IMAGEPATH="$top_srcdir/scripts/image" DOCFILE="$builddir/doc/interpreter/doc-cache" +BUILT_IN_DOCSTRINGS_FILE="$builddir/libinterp/DOCSTRINGS" TEXIMACROSFILE="$top_srcdir/doc/interpreter/macros.texi" INFOFILE="$top_srcdir/doc/interpreter/octave.info" @@ -60,6 +61,11 @@ ## Frontends for gdb (e.g. Emacs's GUD mode) need --annotate=3 driver="gdb --annotate=3 --args" shift + elif [ "x$1" = "x-gud2" ]; then + ## The latest version of gud needs -i=mi. There isn't a good way to check + ## this at configure time, so we just add a gdb2 flag + driver="gdb -i=mi --args" + shift elif [ "x$1" = "x-valgrind" ]; then driver="valgrind --tool=memcheck" shift @@ -73,8 +79,9 @@ fi OCTAVE_SITE_INITFILE="$top_srcdir/scripts/startup/main-rcfile" \ -OCTAVE_DEFAULT_QT_SETTINGS="$top_srcdir/gui/default-qt-settings" \ +OCTAVE_DEFAULT_QT_SETTINGS="$top_srcdir/libgui/default-qt-settings" \ exec $builddir/libtool --mode=execute $driver \ "$octave_executable" --no-init-path --path="$LOADPATH" \ --image-path="$IMAGEPATH" --doc-cache-file="$DOCFILE" \ + --built-in-docstrings-file="$BUILT_IN_DOCSTRINGS_FILE" \ --texi-macros-file="$TEXIMACROSFILE" --info-file="$INFOFILE" "$@"
--- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's scripts directory +# Makefile for Octave's scripts directory # # Copyright (C) 1993-2012 John W. Eaton #
--- a/scripts/audio/wavread.m +++ b/scripts/audio/wavread.m @@ -76,6 +76,7 @@ if (riff_size == -1) error ("wavread: file contains no RIFF chunk"); endif + riff_size = min (riff_size, file_size - riff_pos); riff_type = char (fread (fid, 4))'; if (! strcmp (riff_type, "WAVE")) @@ -100,6 +101,7 @@ if (data_size == -1) error ("wavread: file contains no data chunk"); endif + data_size = min (data_size, file_size - data_pos); ### Read format chunk. fseek (fid, fmt_pos, "bof");
--- a/scripts/audio/wavwrite.m +++ b/scripts/audio/wavwrite.m @@ -23,7 +23,8 @@ ## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename} ## with sample rate @var{Fs} and bits per sample @var{bps}. The ## default sample rate is 8000 Hz with 16-bits per sample. Each column -## of the data represents a separate channel. +## of the data represents a separate channel. If @var{y} is either a +## row vector or a column vector, it is written as a single channel. ## @seealso{wavread} ## @end deftypefn @@ -50,11 +51,20 @@ endif endif + ## calculate filesize + [n, channels] = size (y); + + ## allow y to be a row vector + if (n == 1) + n = channels; + channels = 1; + endif + ## test arguments - if (columns (y) < 1) + if (channels < 1) error ("wavwrite: Y must have at least one column"); endif - if (columns (y) > 0x7FFF) + if (channels > 0x7FFF) error ("wavwrite: Y has more than 32767 columns (too many for a WAV-file)"); endif @@ -70,9 +80,6 @@ error ("wavwrite: sample resolution not supported"); endswitch - ## calculate filesize - [n, channels] = size (y); - ## size of data chunk ck_size = n*channels*(bits_per_sample/8); @@ -174,10 +181,19 @@ %! unlink (fname); % %!test -%! A = [-2:2]; +%! A = [-2:2]'; %! wavwrite (A, fname); %! B = wavread (fname); %! B *= 32768; -%! assert (B, [-32768 -32768 0 32767 32767]); +%! assert (B, [-32768 -32768 0 32767 32767]'); +%! unlink (fname); +% +%!test +%! A = [-1:0.1:1]; +%! wavwrite (A, fname); +%! [B, samples_per_sec, bits_per_sample] = wavread (fname); +%! assert (A', B, 1/2^15); +%! assert (samples_per_sec, 8000); +%! assert (bits_per_sample, 16); %! unlink (fname);
--- a/scripts/general/interp1.m +++ b/scripts/general/interp1.m @@ -205,7 +205,7 @@ error ("interp1: extra points in discontinuities"); endif else - error ("interp1: discontinuities not supported for method `%s'", method); + error ("interp1: discontinuities not supported for method '%s'", method); endif endif endif
--- a/scripts/general/interp2.m +++ b/scripts/general/interp2.m @@ -397,7 +397,7 @@ ZI (!inside) = extrapval; else - error ("interp2: input data must have `meshgrid' format"); + error ("interp2: input data must have 'meshgrid' format"); endif elseif (strcmp (method, "spline")) @@ -405,7 +405,7 @@ ZI = __splinen__ ({Y(:,1).', X(1,:)}, Z, {YI(:,1), XI(1,:)}, extrapval, "spline"); else - error ("interp2: input data must have `meshgrid' format"); + error ("interp2: input data must have 'meshgrid' format"); endif else error ("interp2: interpolation METHOD not recognized");
--- a/scripts/general/interp3.m +++ b/scripts/general/interp3.m @@ -91,7 +91,7 @@ if (ndims (v) != 3) error ("interp3: expect 3-dimensional array of values"); endif - x = varargin (2:end); + x = varargin (2:nargs); if (any (! cellfun (@isvector, x))) for i = 2 : 3 if (! size_equal (x{1}, x{i})) @@ -137,15 +137,48 @@ %!test -%! x = y = z = -1:1; +%! x = y = z = -1:1; y = y + 2; %! f = @(x,y,z) x.^2 - y - z.^2; %! [xx, yy, zz] = meshgrid (x, y, z); %! v = f (xx,yy,zz); -%! xi = yi = zi = -1:0.5:1; +%! xi = yi = zi = -1:0.5:1; yi = yi + 2.1; %! [xxi, yyi, zzi] = meshgrid (xi, yi, zi); %! vi = interp3 (x, y, z, v, xxi, yyi, zzi); -%! [xxi, yyi, zzi] = ndgrid (xi, yi, zi); -%! vi2 = interpn (x, y, z, v, xxi, yyi, zzi); +%! [xxi, yyi, zzi] = ndgrid (yi, xi, zi); +%! vi2 = interpn (y, x, z, v, xxi, yyi, zzi); +%! tol = 10 * eps; +%! assert (vi, vi2, tol); + +%!test +%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]); v(:,2,1)=[7 ;5;4]; v(:,1,2)=[2 ;3;5]; +%! [xxi3, yyi3, zzi3] = meshgrid (xi, yi, zi); +%! [xxi, yyi, zzi] = ndgrid (yi, xi, zi); +%! vi = interp3 (x, y, z, v, xxi3, yyi3, zzi3, "nearest"); +%! vi2 = interpn (y, x, z, v, xxi, yyi, zzi,"nearest"); +%! assert (vi, vi2); + +%!test +%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]); v(:,2,1)=[7 ;5;4]; v(:,1,2)=[2 ;3;5]; +%! vi = interp3 (x, y, z, v, xi+1, yi, zi, "nearest",3); +%! vi2 = interpn (y, x, z, v, yi, xi+1, zi,"nearest", 3); +%! assert (vi, vi2); + +%!test +%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]); v(:,2,1)=[7 ;5;4]; v(:,1,2)=[2 ;3;5]; +%! vi = interp3 (x, y, z, v, xi, yi, zi, "nearest"); +%! vi2 = interpn (y, x, z, v, yi, xi, zi,"nearest"); +%! assert (vi, vi2); + +%!test +%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]); v(:,2,1)=[7 ;5;4]; v(:,1,2)=[2 ;3;5]; +%! vi = interp3 (v, xi, yi, zi, "nearest",3); +%! vi2 = interpn (v, yi, xi, zi,"nearest", 3); +%! assert (vi, vi2); + +%!test +%! xi=zi=.6:1.6; yi=1; v=ones([3,2,2]); v(:,2,1)=[7 ;5;4]; v(:,1,2)=[2 ;3;5]; +%! vi = interp3 (v, xi, yi, zi, "nearest"); +%! vi2 = interpn (v, yi, xi, zi,"nearest"); %! assert (vi, vi2); %!shared z, zout, tol
--- a/scripts/general/repmat.m +++ b/scripts/general/repmat.m @@ -40,24 +40,48 @@ endif if (nargin == 3) - if (! (isscalar (m) && isscalar (n))) - error ("repmat: with 3 arguments M and N must be scalar"); + if (! isempty (m) && isempty (n)) + m = m(:).'; + n = 1; + elseif (isempty (m) && ! isempty (n)) + m = n(:).'; + n = 1; + elseif (isempty (m) && isempty (n)) + m = n = 1; + else + if (all (size (m) > 1)) + m = m(:,1); + if (numel (m) < 3) + n = n(end); + else + n = []; + endif + endif + if (all (size (n) > 1)) + n = n(:,1); + endif + m = m(:).'; + n = n(:).'; endif - idx = [m, n]; else - if (isscalar (m)) - idx = [m, m]; + if (isempty (m)) + m = n = 1; + elseif (isscalar (m)) n = m; - elseif (isvector (m) && length (m) > 1) - ## Ensure that we have a row vector - idx = m(:).'; + elseif (ndims (m) > 2) + error ("repmat: M has more than 2 dimensions") + elseif (all (size (m) > 1)) + m = m(:,1).'; + n = []; else - error ("repmat: invalid dimensional argument"); + m = m(:).'; + n = []; endif endif + idx = [m, n]; if (all (idx < 0)) - error ("repmat: invalid dimensions"); + error ("repmat: invalid dimensions") else idx = max (idx, 0); endif @@ -101,6 +125,20 @@ endfunction +# Tests for ML compatibility +%!shared x +%! x = [1 2 3]; +%!assert (repmat (x, [3, 1]), repmat (x, 3, [])) +%!assert (repmat (x, [3, 1]), repmat (x, [], 3)) +%!assert (repmat (x, [1, 3]), repmat (x, [], [1, 3])) +%!assert (repmat (x, [1, 3]), repmat (x, [1, 3], [])) +%!assert (repmat (x, [1 3]), repmat (x, [1 3; 3 3])) +%!assert (repmat (x, [1 1 2]), repmat (x, [1 1; 1 3; 2 1])) +%!assert (repmat (x, [1 3; 1 3], [1; 3]), repmat (x, [1 1 3])) +%!assert (repmat (x, [1 1], 4), repmat (x, [1 3; 1 3], [1; 4])) +%!assert (repmat (x, [1 1], 4), repmat (x, [1 3; 1 3], [1 2; 3 4])) +%!assert (repmat (x, [1 1], 4), repmat (x, [1 1 4])); +%!assert (repmat (x, [1 1], 4), repmat (x, 1, [1 4])); # Test various methods of providing size parameters %!shared x
--- a/scripts/geometry/voronoi.m +++ b/scripts/geometry/voronoi.m @@ -105,10 +105,7 @@ linespec = varargin(narg); endif - lx = length (x); - ly = length (y); - - if (lx != ly) + if (length (x) != length (y)) error ("voronoi: X and Y must be vectors of the same length"); endif @@ -133,35 +130,33 @@ [[x(:) ; xbox(:)], [y(:); ybox(:)]], opts{:}); - idx = find (! infi); - ll = length (idx); - c = c(idx).'; - k = sum (cellfun ("length", c)); + c = c(! infi).'; + ## Delete null entries which cause problems in next cellfun function + c(cellfun ("isempty", c)) = []; edges = cell2mat (cellfun (@(x) [x ; [x(end), x(1:end-1)]], c, "uniformoutput", false)); ## Identify the unique edges of the Voronoi diagram edges = sortrows (sort (edges).').'; - edges = edges (:, [(edges(1, 1: end - 1) != edges(1, 2 : end) | ... - edges(2, 1 :end - 1) != edges(2, 2 : end)), true]); + edges = edges(:, [(edges(1, 1 :end - 1) != edges(1, 2 : end) | ... + edges(2, 1 :end - 1) != edges(2, 2 : end)), true]); ## Eliminate the edges of the diagram representing the box - poutside = (1 : rows (p)) ... - (p (:, 1) < xmin - xdelta | p (:, 1) > xmax + xdelta | ... - p (:, 2) < ymin - ydelta | p (:, 2) > ymax + ydelta); - edgeoutside = ismember (edges (1, :), poutside) & ... - ismember (edges (2, :), poutside); - edges (:, edgeoutside) = []; + poutside = (1:rows (p)) ... + (p(:, 1) < xmin - xdelta | p(:, 1) > xmax + xdelta | ... + p(:, 2) < ymin - ydelta | p(:, 2) > ymax + ydelta); + edgeoutside = ismember (edges(1, :), poutside) & ... + ismember (edges(2, :), poutside); + edges(:, edgeoutside) = []; ## Get points of the diagram Vvx = reshape (p(edges, 1), size (edges)); Vvy = reshape (p(edges, 2), size (edges)); if (nargout < 2) + h = plot (handl, Vvx, Vvy, linespec{:}, x, y, '+'); lim = [xmin, xmax, ymin, ymax]; - h = plot (handl, Vvx, Vvy, linespec{:}, x, y, '+'); - axis (lim + 0.1 * [[-1, 1] * (lim (2) - lim (1)), ... - [-1, 1] * (lim (4) - lim (3))]); + axis (lim + 0.1 * [[-1, 1] * xdelta, [-1, 1] * ydelta]); if (nargout == 1) vx = h; endif
rename from scripts/help/unimplemented.m rename to scripts/help/__unimplemented__.m --- a/scripts/help/unimplemented.m +++ b/scripts/help/__unimplemented__.m @@ -18,27 +18,39 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} unimplemented () -## Undocumented internal function. +## @deftypefn {Function File} {@var{txt} =} unimplemented (@var{fcn}) +## Return specific help text for the unimplemented function @var{fcn}. +## This is usually a suggestion for an existing compatible function to use in +## place of @var{fcn}. +## +## This function is not called by users, but by the Octave interpreter when +## it fails to recognize an input string as a valid function name. See +## @code{missing_function_hook} for using a different handler for this event. +## @seealso{missing_function_hook} ## @end deftypefn -function txt = unimplemented (fcn) + +function txt = __unimplemented__ (fcn) + + if (nargin != 1) + print_usage (); + endif is_matlab_function = true; ## Some smarter cases, add more as needed. switch (fcn) - case "importdata" - txt = ["importdata is not implemented. Similar functionality is ",... - "available through @code{load}, @code{dlmread}, @code{csvread}, ",... - "or @code{textscan}."]; - case "quad2d" txt = ["quad2d is not implemented. Consider using dblquad."]; case "gsvd" txt = ["gsvd is not currently part of core Octave. See the ",... + "linear-algebra package at ",... + "@url{http://octave.sourceforge.net/linear-algebra/}."]; + + case "funm" + txt = ["funm is not currently part of core Octave. See the ",... "linear-algebra package at @url{http://octave.sf.net/linear-algebra/}."]; case "linprog" @@ -50,11 +62,28 @@ txt = ["Octave provides lsode for solving differential equations. ",... "For more information try @code{help lsode}. ",... "Matlab-compatible ODE functions are provided by the odepkg package. ",... - "See @url{http://octave.sf.net/odepkg/}."]; + "See @url{http://octave.sourceforge.net/odepkg/}."]; + + case {"javaArray", "javaMethod", "javaMethodEDT", "javaObject", "javaObjectEDT", "javaaddpath", "javaclasspath", "javarmpath"} + txt = ["Java objects and methods can be used with the java package. ",... + "See @url{http://octave.sf.net/java/}."]; + + case {"errordlg", "helpdlg", "inputdlg", "listdlg", "questdlg", "warndlg"} + txt = ["Several dialog functions are provided in the java package. ",... + "See @url{http://octave.sf.net/java/}."]; + + case {"xlsread", "xlsfinfo", "xlswrite", "wk1read", "wk1finfo", "wk1write"} + txt = ["Functions for spreadsheet style I/O (.xls .xlsx .sxc .ods .dbf .wk1 etc.) " , ... + "are provided in the io package. ",... + "See @url{http://octave.sf.net/io/}."]; + + case {"avifile", "aviinfo", "aviread"} + txt = ["Basic video file support is provided in the video package. ",... + "See @url{http://octave.sf.net/video/}."]; otherwise if (ismember (fcn, missing_functions ())) - txt = sprintf ("the `%s' function is not yet implemented in Octave", fcn); + txt = sprintf ("the '%s' function is not yet implemented in Octave", fcn); else is_matlab_function = false; txt = ""; @@ -92,9 +121,6 @@ "aufinfo", "auread", "auwrite", - "avifile", - "aviinfo", - "aviread", "bar3", "bar3h", "bench", @@ -167,7 +193,6 @@ "echodemo", "ellipj", "ellipke", - "errordlg", "evalc", "exifread", "expint", @@ -178,13 +203,11 @@ "fitsinfo", "fitsread", "flow", - "fminsearch", "frame2im", "freqspace", "funm", "gallery", "gammaincinv", - "gco", "getframe", "getpixelposition", "grabcode", @@ -204,7 +227,6 @@ "hdftool", "helpbrowser", "helpdesk", - "helpdlg", "helpwin", "hgexport", "hgload", @@ -218,10 +240,8 @@ "imapprox", "imformats", "import", - "importdata", "inmem", "inputParser", - "inputdlg", "inspect", "instrfind", "instrfindall", @@ -231,15 +251,7 @@ "isjava", "isocaps", "isstudent", - "javaArray", - "javaMethod", - "javaMethodEDT", - "javaObject", - "javaObjectEDT", - "javaaddpath", "javachk", - "javaclasspath", - "javarmpath", "ldl", "libfunctions", "libfunctionsview", @@ -252,7 +264,6 @@ "linkaxes", "linkdata", "linsolve", - "listdlg", "listfonts", "loadlibrary", "lscov", @@ -321,7 +332,6 @@ "publish", "qmr", "quad2d", - "questdlg", "rbbox", "reducepatch", "reducevolume", @@ -392,7 +402,6 @@ "visdiff", "volumebounds", "waitfor", - "warndlg", "waterfall", "wavfinfo", "wavplay", @@ -403,9 +412,6 @@ "wk1read", "wk1write", "workspace", - "xlsfinfo", - "xlsread", - "xlswrite", "xmlread", "xmlwrite", "xslt", @@ -415,10 +421,9 @@ %!test -%! str = unimplemented ("no_name_function"); +%! str = __unimplemented__ ("no_name_function"); %! assert (isempty (str)); -%! str = unimplemented ("quad2d"); +%! str = __unimplemented__ ("quad2d"); %! assert (str(1:51), "quad2d is not implemented. Consider using dblquad."); -%! str = unimplemented ("MException"); -%! assert (str(1:58), "the `MException' function is not yet implemented in Octave"); - +%! str = __unimplemented__ ("MException"); +%! assert (str(1:58), "the 'MException' function is not yet implemented in Octave");
--- a/scripts/help/doc.m +++ b/scripts/help/doc.m @@ -19,12 +19,12 @@ ## -*- texinfo -*- ## @deftypefn {Command} {} doc @var{function_name} ## Display documentation for the function @var{function_name} -## directly from an on-line version of +## directly from an online version of ## the printed manual, using the GNU Info browser. If invoked without ## any arguments, the manual is shown from the beginning. ## ## For example, the command @kbd{doc rand} starts the GNU Info browser -## at the @code{rand} node in the on-line version of the manual. +## at the @code{rand} node in the online version of the manual. ## ## Once the GNU Info browser is running, help for using it is available ## using the command @kbd{C-h}. @@ -92,7 +92,7 @@ if (! (have_fname && status == 0)) status = system (cmd); if (status == 127) - warning ("unable to find info program `%s'", info_program ()); + warning ("unable to find info program '%s'", info_program ()); endif endif
--- a/scripts/help/get_first_help_sentence.m +++ b/scripts/help/get_first_help_sentence.m @@ -66,9 +66,9 @@ case "html" [text, status] = first_sentence_html (help_text, max_len); case "not documented" - error ("get_first_help_sentence: `%s' is not documented\n", name); + error ("get_first_help_sentence: '%s' is not documented\n", name); case "not found" - error ("get_first_help_sentence: `%s' not found\n", name); + error ("get_first_help_sentence: '%s' not found\n", name); otherwise error ("get_first_help_sentence: internal error: unsupported help text format: '%s'\n", format); endswitch
--- a/scripts/help/help.m +++ b/scripts/help/help.m @@ -100,7 +100,7 @@ case "html" [text, status] = strip_html_tags (text); case "not documented" - error ("help: `%s' is not documented\n", name); + error ("help: '%s' is not documented\n", name); case "not found" do_contents (name); return; @@ -197,7 +197,7 @@ msg = feval (missing_function_hook, name); if (isempty (msg)) - msg = sprintf ("`%s' not found", name); + msg = sprintf ("'%s' not found", name); endif error ("help: %s\n", msg);
--- a/scripts/help/module.mk +++ b/scripts/help/module.mk @@ -6,6 +6,7 @@ help_FCN_FILES = \ help/__makeinfo__.m \ + help/__unimplemented__.m \ help/doc.m \ help/gen_doc_cache.m \ help/get_first_help_sentence.m \ @@ -13,7 +14,6 @@ help/lookfor.m \ help/print_usage.m \ help/type.m \ - help/unimplemented.m \ help/which.m \ $(help_PRIVATE_FCN_FILES)
--- a/scripts/help/print_usage.m +++ b/scripts/help/print_usage.m @@ -33,14 +33,15 @@ if (numel (x) > 1) name = x (2).name; else - error ("print_usage: invalid function\n"); + error ("Octave:invalid-context", "print_usage: invalid function\n"); endif fullpath = evalin ("caller", "mfilename (""fullpath"")"); if (strcmp (fullpath(end-length(name)+1:end), name)) fullname = [fullpath, ".m"]; endif elseif (!ischar (name)) - error ("print_usage: input argument must be a string"); + error ("Octave:invalid-input-arg", + "print_usage: input argument must be a string"); else fullname = name; endif @@ -59,9 +60,9 @@ case "html" [usage_string, status] = get_usage_html (text, max_len); case "not documented" - error ("print_usage: `%s' is not documented\n", name); + error ("print_usage: '%s' is not documented\n", name); case "not found" - error ("print_usage: `%s' not found\n", name); + error ("print_usage: '%s' not found\n", name); otherwise error ("print_usage: internal error: unsupported help text format: '%s'\n", format); endswitch @@ -73,7 +74,7 @@ endif if (at_toplev) - error ("Invalid call to %s. Correct usage is:\n\n%s\n%s", + error ("Octave:invalid-fun-call", "Invalid call to %s. Correct usage is:\n\n%s\n%s", name, usage_string, __additional_help_message__ ()); else msg = sprintf ("Invalid call to %s. Correct usage is:\n\n%s", @@ -84,7 +85,7 @@ msg(end) = " "; endif - error (msg); + error ("Octave:invalid-fun-call", msg); endif endfunction @@ -139,4 +140,3 @@ ## Stop reporting function as missing tests. No good tests possible. %!assert (1) -
--- a/scripts/help/private/__additional_help_message__.m +++ b/scripts/help/private/__additional_help_message__.m @@ -28,8 +28,8 @@ else msg = "\ Additional help for built-in functions and operators is\n\ -available in the on-line version of the manual. Use the command\n\ -`doc <topic>' to search the manual index.\n\ +available in the online version of the manual. Use the command\n\ +'doc <topic>' to search the manual index.\n\ \n\ Help and information about Octave is also available on the WWW\n\ at http://www.octave.org and via the help@octave.org\n\
--- a/scripts/help/type.m +++ b/scripts/help/type.m @@ -73,13 +73,13 @@ if (isempty (file)) ## 'name' is an ordinary file, and not a function name. ## FIXME: Should we just print it anyway? - error ("type: `%s' undefined\n", name); + error ("type: '%s' undefined\n", name); endif ## Read the file fid = fopen (file, "r"); if (fid < 0) - error ("type: couldn't open `%s' for reading", file); + error ("type: couldn't open '%s' for reading", file); endif contents = char (fread (fid).'); fclose (fid); @@ -99,7 +99,7 @@ elseif (any (strcmp (__keywords__ (), name))) text = sprintf ("%s is a keyword", name); else - error ("type: `%s' undefined\n", name); + error ("type: '%s' undefined\n", name); endif ## Should we return the text or print if
--- a/scripts/help/which.m +++ b/scripts/help/which.m @@ -32,15 +32,15 @@ for i = 1:nargin if (isempty (m(i).file)) if (! isempty (m(i).type)) - printf ("`%s' is a %s\n", + printf ("'%s' is a %s\n", m(i).name, m(i).type); endif else if (isempty (m(i).type)) - printf ("`%s' is the file %s\n", + printf ("'%s' is the file %s\n", m(i).name, m(i).file); else - printf ("`%s' is a %s from the file %s\n", + printf ("'%s' is a %s from the file %s\n", m(i).name, m(i).type, m(i).file); endif endif
--- a/scripts/image/cmpermute.m +++ b/scripts/image/cmpermute.m @@ -54,9 +54,7 @@ error ("cmpermute: X must be an indexed image"); endif - if (! isnumeric (map) || iscomplex (map) - || ndims (map) != 2 || columns (map) != 3 - || any (map(:) < 0) || any (map(:) > 1)) + if (! iscolormap (map)) error ("cmpermute: MAP must be a valid colormap"); endif
--- a/scripts/image/cmunique.m +++ b/scripts/image/cmunique.m @@ -68,9 +68,7 @@ if (nargin == 2) ## (X, map) case - if (! isnumeric (map) || iscomplex (map) - || ndims (map) != 2 || columns (map) != 3 - || any (map(:) < 0) || any (map(:) > 1)) + if (! iscolormap (map)) error ("cmunique: MAP must be a valid colormap"); endif [newmap,i,j] = unique (map, "rows"); # calculate unique colormap
--- a/scripts/image/imwrite.m +++ b/scripts/image/imwrite.m @@ -161,13 +161,8 @@ else error ("imwrite: %s: invalid class for indexed image data", img_class); endif - if (isa (map, "double")) - if (ndims (map) != 2 || columns (map) != 3) - error ("imwrite: invalid size for colormap"); - endif - else - error ("imwrite: %s invalid class for indexed image colormap", - class (map)); + if (! iscolormap (map)) + error ("imwrite: invalid indexed image colormap"); endif ## FIXME -- we should really be writing indexed images here but
--- a/scripts/image/ind2rgb.m +++ b/scripts/image/ind2rgb.m @@ -46,7 +46,7 @@ endif ## Check the color map. - if (ndims (map) != 2 || columns (map) != 3) + if (! iscolormap (map)) error ("ind2rgb: MAP must be a valid colormap"); endif
new file mode 100644 --- /dev/null +++ b/scripts/image/iscolormap.m @@ -0,0 +1,52 @@ +## Copyright (C) 2012 Carnë Draug +## +## This file is part of Octave. +## +## Octave 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. +## +## Octave 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 Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} iscolormap (@var{cmap}) +## Return true if @var{cmap} is a colormap. +## +## A colormap is an @var{n} row by 3 column matrix. The columns contain red, +## green, and blue intensities respectively. All entries must be between 0 +## and 1 inclusive. +## +## @seealso{colormap, rgbplot} +## @end deftypefn + +## Author: Carnë Draug <carandraug+dev@gmail.com> + +function retval = iscolormap (cmap) + + if (nargin != 1) + print_usage; + endif + + retval = (isnumeric (cmap) && isreal (cmap) && + columns (cmap) == 3 && ndims (cmap) == 2 && isa (cmap, "double") && + min (cmap(:)) >= 0 && max (cmap(:)) <= 1); + +endfunction + + +%!assert (iscolormap (jet (64))) +%!assert (iscolormap ({0 1 0}), false) +%!assert (iscolormap ([0 1i 0]), false) +%!assert (iscolormap (ones (3,4)), false) +%!assert (iscolormap (ones (3,3,3)), false) +%!assert (iscolormap (single (jet (64))), false) +%!assert (iscolormap ([0 0 -2]), false) +%!assert (iscolormap ([0 0 2]), false)
--- a/scripts/image/module.mk +++ b/scripts/image/module.mk @@ -18,6 +18,7 @@ image/hot.m \ image/hsv.m \ image/hsv2rgb.m \ + image/iscolormap.m \ image/image.m \ image/imagesc.m \ image/imfinfo.m \
--- a/scripts/image/rgbplot.m +++ b/scripts/image/rgbplot.m @@ -17,31 +17,37 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} rgbplot (@var{cmap}) +## @deftypefn {Function File} {} rgbplot (@var{cmap}) +## @deftypefnx {Function File} {@var{h} =} rgbplot (@var{cmap}) ## Plot the components of a colormap. ## ## The first column is plotted in red, the second column in green, and ## the third column in blue. The values are between 0 and 1 and represent ## the intensity of the RGB components in the given indexed color. +## +## The optional return value @var{h} is a graphics handle to the created plot. +## ## @seealso{colormap} ## @end deftypefn -function rgbplot (cmap) +function retval = rgbplot (cmap) if (nargin != 1) print_usage (); endif - if (! ismatrix (cmap) || ndims (cmap) != 2 || columns (cmap) != 3) - error ("rgbplot: CMAP must be a matrix of size Nx3"); - elseif (any (cmap(:) < 0) || any (cmap(:) > 1)) - error ("rgbplot: CMAP intensities must be in the range [0, 1]"); + if (! iscolormap (cmap)) + error ("rgbplot: CMAP must be a colormap"); endif - plot (cmap(:,1),"r", cmap(:,2),"g", cmap(:,3),"b"); + h = plot (cmap(:,1),"r", cmap(:,2),"g", cmap(:,3),"b"); set (gca, 'ytick', 0:0.1:1); xlabel ("color index"); + if (nargout > 0) + retval = h; + endif + endfunction @@ -52,9 +58,4 @@ %%test input validation %!error rgbplot () %!error rgbplot (1,2) -%!error <CMAP must be a matrix of size Nx3> rgbplot ({0 1 0}) -%!error <CMAP must be a matrix of size Nx3> rgbplot (ones (3,3,3)) -%!error <CMAP must be a matrix of size Nx3> rgbplot (ones (3,4)) -%!error <CMAP intensities must be in the range> rgbplot ([0 0 -2]) -%!error <CMAP intensities must be in the range> rgbplot ([0 0 2]) - +%!error <CMAP must be a colormap> rgbplot ({0 1 0})
new file mode 100644 --- /dev/null +++ b/scripts/io/importdata.m @@ -0,0 +1,414 @@ +## Copyright (C) 2012 Erik Kjellson +## +## This file is part of Octave. +## +## Octave 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. +## +## Octave 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 Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{A} =} importdata (@var{fname}) +## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}) +## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}, @var{header_rows}) +## @deftypefnx {Function File} {[@var{A}, @var{delimiter}] =} importdata (...) +## @deftypefnx {Function File} {[@var{A}, @var{delimiter}, @var{header_rows}] =} importdata (...) +## Importing data from file. +## +## Importing the contents of file @var{fname} into workspace. +## +## Input parameters: +## @itemize +## @item @var{fname} +## The file name for the file to import. +## +## @item @var{delimiter} +## The character separating columns of data. Use @code{\t} for tab. +## (Only valid for ascii files) +## +## @item @var{header_rows} +## Number of header rows before the data begins. (Only valid for ascii files) +## @end itemize +## +## Different file types are supported: +## @itemize +## @item Ascii table +## +## Importing ascii table using the specified number of header rows and +## the specified delimiter. +## +## @item Image file +## +## @item @sc{Matlab} file +## +## @item Spreadsheet files (depending on external software) +## +## @item Wav file +## +## @end itemize +## +## @seealso{textscan, dlmread, csvread, load} +## @end deftypefn + +## Author: Erik Kjellson <erikiiofph7@users.sourceforge.net> + +function [output, delimiter, header_rows] = importdata (varargin) + + ## Default values + fname = ""; + delimiter = ""; + header_rows = -1; + + ########## + + ## Check input arguments + + if (nargin < 1) + print_usage (); + endif + + fname = varargin{1}; + ## Check that the file name really is a string + if (! ischar (fname)) + error ("importdata: file name needs to be a string"); + endif + if ( strcmpi (fname, "-pastespecial")) + error ("importdata: option -pastespecial not implemented"); + endif + + if (nargin > 1) + delimiter = varargin{2}; + ## Check that the delimiter really is a string + if (!ischar (delimiter)) + error("importdata: delimiter needs to be a character"); + endif + if (length (delimiter) > 1 && !strcmpi (delimiter, "\\t")) + error("importdata: delimiter cannot be longer than 1 character"); + endif + if (strcmpi (delimiter, "\\")) + delimiter = "\\\\"; + endif + endif + + if (nargin > 2) + header_rows = varargin{3}; + if (!isnumeric (header_rows) || header_rows < 0) + error ("importdata: number of header rows needs to be an integer number >= 0"); + endif + endif + + if (nargin > 3) + error ("importdata: too many input arguments"); + endif + + ########## + + ## Check file format + ## Get the extension from the file name. + [d n fileExt v] = fileparts (fname); + ## Make sure file extension is in lower case. + fileExt = lower (fileExt); + + switch fileExt + case {".au", ".snd"} + error (sprintf ("importdata: not implemented for file format %s", + fileExt)); + case ".avi" + error (sprintf ("importdata: not implemented for file format %s", + fileExt)); + case {".bmp", ".cur", ".gif", ".hdf", ".ico", ".jpe", ".jpeg", ".jpg", \ + ".pbm", ".pcx", ".pgm", ".png", ".pnm", ".ppm", ".ras", \ + ".tif", ".tiff", ".xwd"} + delimiter = NaN; + header_rows = 0; + [output.cdata, output.colormap, output.alpha] = imread (fname); + case ".mat" + delimiter = NaN; + header_rows = 0; + output = load (fname); + case {".wk1", ".xls", ".xlsx", ".dbf", ".pxl"} + ## If there's no Excel file support simply fall back to unimplemented.m + output = xlsread (fname); + case {".ods", ".sxc", ".fods", ".uos", ".xml"} + ## unimplemented.m only knows ML functions; odsread isn't one but is in OF + try + output = odsread (fname); + catch + ## Fall back to unimplemented.m. + output = xlsread (fname); + end_try_catch + case {".wav", ".wave"} + delimiter = NaN; + header_rows = 0; + [output.data, output.fs] = wavread (fname); + otherwise + ## Assume the file is in ascii format. + [output, delimiter, header_rows] = \ + importdata_ascii (fname, delimiter, header_rows); + endswitch + + ## If there are any empty fields in the output structure, then remove them + if (isstruct (output) && length (output) == 1) + fields = fieldnames (output); + for i=1:length (fields) + if (isempty (getfield (output, fields{i}))) + output = rmfield (output, fields{i}); + endif + endfor + + ## If only one field is left, replace the structure with the field, + ## i.e. output = output.onlyFieldLeft + + ## Update the list of fields + fields = fieldnames (output); + if (length (fields) == 1) + output = getfield (output, fields{1}); + endif + endif +endfunction + + +######################################## + +function [output, delimiter, header_rows] = \ + importdata_ascii (fname, delimiter, header_rows) + + ## Define the fields in the output structure so that the order will be + ## correct. + + output.data = []; + output.textdata = []; + output.rowheaders = []; + output.colheaders = []; + + ## Read file into string and count the number of header rows + file_content = fileread (fname); + + ## Split the file into rows (using \r\n or \n as delimiters between rows). + file_content_rows = regexp (file_content, "\r?\n", "split"); + + ## FIXME: guess delimiter, if it isn't defined + if (isempty (delimiter)) + error ("importdata: Guessing delimiter is not implemented yet, you have to specify it."); + endif + + ## FIXME: A more intelligent way to count number of header rows. This + ## is needed e.g. when delimiter=' ' and the header contains spaces... + + ## If number of header rows is undefined, then count the number of + ## header rows by step through row by row and look for the delimiter. + ## Assume that the header can't contain any delimiter. + if (header_rows < 0) + header_rows = 0; + for i=1:length (file_content_rows) + if (isempty (regexp(file_content_rows{i}, delimiter, "once"))) + header_rows++; + else + ## Data part has begun and therefore no more header rows can be + ## found + break; + endif + endfor + endif + + ## Put the header rows in output.textdata. + if (header_rows > 0) + output.textdata = file_content_rows (1:header_rows)'; + endif + + ## If space is the delimiter, then remove spaces in the beginning of + ## each data row. + if (strcmpi (delimiter, " ")) + for i=(header_rows+1):length (file_content_rows) + ## strtrim does not only remove the leading spaces but also the + ## tailing spaces, but that doesn't really matter. + file_content_rows{i} = strtrim (file_content_rows{i}); + endfor + endif + + ## Remove empty data rows. Go through them backwards so that you wont + ## get out of bounds. + for i=length (file_content_rows):-1:(header_rows + 1) + if (length (file_content_rows{i}) < 1) + file_content_rows = [file_content_rows(1:i-1), \ + file_content_rows(i+1:length(file_content_rows))]; + endif + endfor + + ## Count the number of data columns. If there are different number of + ## columns, use the greatest value. + data_columns = 0; + delimiter_pattern = delimiter; + ## If space is the delimiter, then multiple spaces should count as ONE + ## delimiter. Also ignore leading spaces. + if (strcmpi (delimiter, " ")) + delimiter_pattern = ' +'; + endif + for i=(header_rows+1):length(file_content_rows) + data_columns = max (data_columns, + length (regexp (file_content_rows{i}, + delimiter_pattern, "split"))); + endfor + + ## Go through the data and put it in either output.data or + ## output.textdata depending on if it is numeric or not. + output.data = NaN (length (file_content_rows) - header_rows, data_columns); + for i=(header_rows+1):length(file_content_rows) + ## Only use the row if it contains anything other than white-space + ## characters. + if (any (file_content_rows{i} != " ")) + row_data = regexp (file_content_rows{i}, delimiter_pattern, "split"); + + for j=1:length(row_data) + ## Try to convert the column to a number, if it works put it in + ## output.data, otherwise in output.textdata + if (!isempty (row_data{j})) + data_numeric = str2double (row_data{j}); + if (!isempty (data_numeric)) + output.data(i-header_rows, j) = data_numeric; + else + output.textdata{i,j} = row_data{j}; + endif + endif + endfor + + endif + endfor + + ## Check wether rowheaders or colheaders should be used + if ((header_rows == data_columns) && (size (output.textdata, 2) == 1)) + output.rowheaders = output.textdata; + elseif (size (output.textdata, 2) == data_columns) + output.colheaders = output.textdata(end,:); + endif + + ## When delimiter = "\\t" convert it to a tab, done for Matlab compatibility. + if (strcmp (delimiter, '\t')) + delimiter = "\t"; + endif + +endfunction + + +######################################## + +%!test +%! # Comma separated values +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "3.1,-7.2,0\n0.012,6.5,128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, ","); +%! unlink (fn); +%! assert (a, A); +%! assert (d, ","); +%! assert (h, 0); + +%!test +%! # Tab separated values +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, "\\t"); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 0); + +%!test +%! # Space separated values, using multiple spaces to align in columns. +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(1,:)); +%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(2,:)); +%! fclose (fid); +%! [a,d,h] = importdata (fn, " "); +%! unlink (fn); +%! assert (a, A); +%! assert (d, " "); +%! assert (h, 0); + +%!test +%! # Header +%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; +%! A.textdata = {"This is a header row."; \ +%! "this row does not contain any data, but the next one does."}; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, [A.textdata{1} "\n"]); +%! fputs (fid, [A.textdata{2} "\n"]); +%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, "\\t"); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 2); + +%!test +%! # Ignore empty rows containing only spaces +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(1,:)); +%! fputs (fid, " "); +%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(2,:)); +%! fclose (fid); +%! [a,d,h] = importdata (fn, " "); +%! unlink (fn); +%! assert (a, A); +%! assert (d, " "); +%! assert (h, 0); + +%!test +%! # Exponentials +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "+3.1e0\t-72E-1\t0\n12e-3\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, "\\t"); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 0); + +%!test +%! # Missing values +%! A = [3.1 NaN 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "3.1\t\t0\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, "\\t"); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 0); + +%!test +%! # CRLF for line breaks +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "3.1\t-7.2\t0\r\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, "\\t"); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 0); +
--- a/scripts/io/module.mk +++ b/scripts/io/module.mk @@ -6,6 +6,7 @@ io/csvwrite.m \ io/dlmwrite.m \ io/fileread.m \ + io/importdata.m \ io/is_valid_file_id.m \ io/strread.m \ io/textscan.m \
--- a/scripts/io/strread.m +++ b/scripts/io/strread.m @@ -405,8 +405,10 @@ ## Check for single delimiter followed/preceded by whitespace if (! isempty (delimiter_str)) dlmstr = setdiff (delimiter_str, " "); - rxp_dlmwsp = sprintf ("( [%s]|[%s] )", dlmstr, dlmstr); - str = regexprep (str, rxp_dlmwsp, delimiter_str(1)); + if (! isempty (dlmstr)) + rxp_dlmwsp = sprintf ('( [%s] | [%s]|[%s] )', dlmstr, dlmstr, dlmstr); + str = regexprep (str, rxp_dlmwsp, delimiter_str(1)); + endif endif ## Wipe leading and trailing whitespace on each line (it may be ## delimiter too) @@ -528,7 +530,7 @@ ## ..or it IS found. Add inferred width of current conversion field iwrdp += index (words{iwrd}(iwrdp+1:end), fmt_words{ii+1}) - 1; endif - elseif (iwrdp < iwrdl) + elseif (iwrdp <= iwrdl) ## No bordering literal to the right => field occupies (rest of) word nxt_wrd = 1; endif @@ -956,6 +958,12 @@ %! assert (isempty (b)); %! assert (isempty (c)); +%% bug #37023 +%!test +%! [a, b] = strread (" 1. 1 \n 2 3 \n", "%f %f", "endofline", "\n"); +%! assert (a, [1; 2], 1e-15); +%! assert (b, [1; 3], 1e-15); + %% Unsupported format specifiers %!test %!error <format specifiers are not supported> strread ("a", "%c")
--- a/scripts/io/textscan.m +++ b/scripts/io/textscan.m @@ -402,3 +402,9 @@ %! R = textscan (['Empty1' char(10)], 'Empty%d %f'); %! assert (R{1}, int32 (1)); %! assert (isempty (R{2}), true); + +%% bug #37023 (actually a strread test) +%!test +%! data = textscan(" 1. 1 \n 2 3\n", '%f %f'); +%! assert (data{1}, [1; 2], 1e-15); +%! assert (data{2}, [1; 3], 1e-15);
--- a/scripts/miscellaneous/cast.m +++ b/scripts/miscellaneous/cast.m @@ -33,7 +33,7 @@ "double"; "single"; "logical"; "char"}))) retval = feval (typ, val); else - error ("cast: type name `%s' is not a built-in type", typ); + error ("cast: type name '%s' is not a built-in type", typ); endif else error ("cast: expecting TYPE name as second argument");
--- a/scripts/miscellaneous/dir.m +++ b/scripts/miscellaneous/dir.m @@ -82,7 +82,7 @@ fn = flst{1}; [st, err, msg] = stat (fn); if (err < 0) - warning ("dir: `stat (%s)' failed: %s", fn, msg); + warning ("dir: 'stat (%s)' failed: %s", fn, msg); nf = 0; elseif (S_ISDIR (st.mode)) flst = readdir (flst{1}); @@ -99,7 +99,7 @@ fn = flst{i}; [st, err, msg] = lstat (fn); if (err < 0) - warning ("dir: `lstat (%s)' failed: %s", fn, msg); + warning ("dir: 'lstat (%s)' failed: %s", fn, msg); else ## If we are looking at a link that points to something, ## return info about the target of the link, otherwise, return @@ -136,7 +136,7 @@ ## Print the structure to the screen. printf ("%s", list_in_columns ({info.name})); else - warning ("dir: nonexistent directory `%s'", directory); + warning ("dir: nonexistent directory '%s'", directory); endif endfunction
--- a/scripts/miscellaneous/edit.m +++ b/scripts/miscellaneous/edit.m @@ -146,7 +146,7 @@ ## Original version by Paul Kienzle distributed as free software in the ## public domain. -function ret = edit (file, state) +function ret = edit (varargin) ## Pick up globals or default them. @@ -157,51 +157,86 @@ "LICENSE", "GPL", "MODE", "async", "EDITINPLACE", false); - ## Make sure the state variables survive "clear functions". + ## Make sure the stateval variables survive "clear functions". mlock; - if (nargin == 2) - switch (toupper (file)) + if (nargin == 1) + ## User has supplied one arg, this can be a single file name + ## or a cell array of strings containing multiple files to be + ## opened + if (iscellstr(varargin{1})) + ## If first arg is a cell array of strings, it becomes the + ## list of files to be edited + editfilelist = varargin{1}; + elseif (ischar(varargin{1})) + ## If first arg is a string, create a cell array of strings + ## of length one (by copying the input cell array) + editfilelist = varargin(1); + else + error('edit: expected file to be a string or cell array of strings'); + endif + elseif (nargin == 2) + ## User has supplied two arguments, these could be two file + ## names, or a combination of editor state name and new value + ## for that state, so first check for the various states + statevar = varargin{1}; + stateval = varargin{2}; + switch (toupper (statevar)) case "EDITOR" - FUNCTION.EDITOR = state; + FUNCTION.EDITOR = stateval; + return case "HOME" - if (! isempty (state) && state(1) == "~") - state = [ default_home, state(2:end) ]; + if (! isempty (stateval) && stateval(1) == "~") + stateval = [ default_home, stateval(2:end) ]; endif - FUNCTION.HOME = state; + FUNCTION.HOME = stateval; + return case "AUTHOR" - FUNCTION.AUTHOR = state; + FUNCTION.AUTHOR = stateval; + return case "EMAIL" - FUNCTION.EMAIL = state; + FUNCTION.EMAIL = stateval; + return case "LICENSE" - FUNCTION.LICENSE = state; + FUNCTION.LICENSE = stateval; + return case "MODE" - if (strcmp (state, "sync") || strcmp (state, "async")) - FUNCTION.MODE = state; + if (strcmp (stateval, "sync") || strcmp (stateval, "async")) + FUNCTION.MODE = stateval; else error ('edit: expected "edit MODE sync|async"'); endif + return case "EDITINPLACE" - if (ischar (state)) - if (strcmpi (state, "true")) - state = true; - elseif (strcmpi (state, "false")) - state = false; + if (ischar (stateval)) + if (strcmpi (stateval, "true")) + stateval = true; + elseif (strcmpi (stateval, "false")) + stateval = false; else - state = eval (state); + stateval = eval (stateval); endif endif - FUNCTION.EDITINPLACE = state; + FUNCTION.EDITINPLACE = stateval; + return case "GET" - if (isfield (FUNCTION, toupper (state))) - ret = FUNCTION.(toupper (state)); + if (isfield (FUNCTION, toupper (stateval))) + ret = FUNCTION.(toupper (stateval)); else ret = FUNCTION; endif + return otherwise - error ('edit: expected "edit EDITOR|HOME|AUTHOR|EMAIL|LICENSE|MODE val"'); + ## If none of the states match, assume both inputs are + ## actually both file names to be opened + editfilelist = varargin; endswitch - return + elseif (nargin > 2) + if (iscellstr(varargin)) + editfilelist = varargin; + else + error('edit: if supplying more than one input all inputs must be strings containing fiel names to open.'); + endif endif ## Start the editor without a file if no file is given. @@ -216,253 +251,267 @@ return; endif - ## Check whether the user is trying to edit a builtin of compiled function. - switch (exist (file)) - case {3, 5} - error ("edit: unable to edit a built-in or compiled function"); - endswitch + if (numel(editfilelist) > 1) + + ## Call edit on each of the files in the list if there are more than 1 + for i = 1:numel(editfilelist) + edit(editfilelist{i}); + endfor - ## Checks for whether the file is - ## absolute or relative should be handled inside file_in_loadpath. - ## That way, it will be possible to look up files correctly given - ## partial path information. For example, you should be able to - ## edit a particular overloaded function by doing any one of - ## - ## edit classname/foo - ## edit classname/foo.m - ## edit @classname/foo - ## edit @classname/foo.m - ## - ## This functionality is needed for other functions as well (at least - ## help and type; there may be more). So the place to fix that is in - ## file_in_loadpath, possibly with some help from the load_path class. + else + + ## Only one file name was supplied, get it from the cell array + file = editfilelist{1}; - ## The code below includes a portion that serves as a place-holder for - ## the changes suggested above. + ## Check whether the user is trying to edit a builtin or compiled function. + switch (exist (file)) + case {3, 5} + error ("edit: unable to edit a built-in or compiled function"); + endswitch - ## Create list of explicit and implicit file names. - filelist = {file}; - ## If file has no extension, add file.m and file.cc to the list. - idx = rindex (file, "."); - if (idx == 0) - ## Create the list of files to look for - filelist = {file}; - if (isempty (regexp (file, '\.m$'))) - ## No ".m" at the end of the file, add to the list. - filelist{end+1} = cat (2, file, ".m"); - endif - if (isempty (regexp (file, '\.cc$'))) - ## No ".cc" at the end of the file, add to the list. - filelist{end+1} = cat (2, file, ".cc"); - endif - endif + ## Checks for whether the file is + ## absolute or relative should be handled inside file_in_loadpath. + ## That way, it will be possible to look up files correctly given + ## partial path information. For example, you should be able to + ## edit a particular overloaded function by doing any one of + ## + ## edit classname/foo + ## edit classname/foo.m + ## edit @classname/foo + ## edit @classname/foo.m + ## + ## This functionality is needed for other functions as well (at least + ## help and type; there may be more). So the place to fix that is in + ## file_in_loadpath, possibly with some help from the load_path class. - ## If the file includes a path, it may be an overloaded function. - if (! strcmp (file, "@") && index (file, filesep)) - ## No "@" at the beginning of the file, add to the list. - numfiles = numel (filelist); - for n = 1:numfiles - filelist{n+numfiles} = cat (2, "@", filelist{n}); - endfor - endif + ## The code below includes a portion that serves as a place-holder for + ## the changes suggested above. - ## Search the entire path for the 1st instance of a file in the list. - fileandpath = ""; - for n = 1:numel (filelist) - filetoedit = file_in_path (path, filelist{n}); - if (! isempty (filetoedit)) - ## The path is explicitly included. - fileandpath = filetoedit; - break; + ## Create list of explicit and implicit file names. + filelist = {file}; + ## If file has no extension, add file.m and file.cc to the list. + idx = rindex (file, "."); + if (idx == 0) + ## Create the list of files to look for + filelist = {file}; + if (isempty (regexp (file, '\.m$'))) + ## No ".m" at the end of the file, add to the list. + filelist{end+1} = cat (2, file, ".m"); + endif + if (isempty (regexp (file, '\.cc$'))) + ## No ".cc" at the end of the file, add to the list. + filelist{end+1} = cat (2, file, ".cc"); + endif endif - endfor + + ## If the file includes a path, it may be an overloaded function. + if (! strcmp (file, "@") && index (file, filesep)) + ## No "@" at the beginning of the file, add to the list. + numfiles = numel (filelist); + for n = 1:numfiles + filelist{n+numfiles} = cat (2, "@", filelist{n}); + endfor + endif - if (! isempty (fileandpath)) - ## If the file exists, then edit it. - if (FUNCTION.EDITINPLACE) - ## Edit in place even if it is protected. - system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), - [], FUNCTION.MODE); - return; - else - ## If the file is modifiable in place then edit it, otherwise make - ## a copy in HOME and then edit it. - fid = fopen (fileandpath, "r+t"); - if (fid < 0) - from = fileandpath; - fileandpath = cstrcat (FUNCTION.HOME, from (rindex (from, filesep):end)); - [status, msg] = copyfile (from, fileandpath, 1); - if (status == 0) - error (msg); - endif - else - fclose (fid); + ## Search the entire path for the 1st instance of a file in the list. + fileandpath = ""; + for n = 1:numel (filelist) + filetoedit = file_in_path (path, filelist{n}); + if (! isempty (filetoedit)) + ## The path is explicitly included. + fileandpath = filetoedit; + break; endif - system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), - [], FUNCTION.MODE); - return; - endif - endif + endfor - ## If editing a new file that is neither a m-file or an oct-file, - ## just edit it. - fileandpath = file; - idx = rindex (file, "."); - name = file(1:idx-1); - ext = file(idx+1:end); - switch (ext) - case {"cc", "m"} - 0; - otherwise - system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), - [], FUNCTION.MODE); - return; - endswitch - - ## The file doesn't exist in path so create it, put in the function - ## template and edit it. - - ## Guess the email name if it was not given. - if (isempty (FUNCTION.EMAIL)) - host = getenv ("HOSTNAME"); - if (isempty (host) && ispc ()) - host = getenv ("COMPUTERNAME"); - endif - if (isempty (host)) - [status, host] = system ("uname -n"); - ## trim newline from end of hostname - if (! isempty (host)) - host = host(1:end-1); + if (! isempty (fileandpath)) + ## If the file exists, then edit it. + if (FUNCTION.EDITINPLACE) + ## Edit in place even if it is protected. + system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), + [], FUNCTION.MODE); + return; + else + ## If the file is modifiable in place then edit it, otherwise make + ## a copy in HOME and then edit it. + fid = fopen (fileandpath, "r+t"); + if (fid < 0) + from = fileandpath; + fileandpath = cstrcat (FUNCTION.HOME, from (rindex (from, filesep):end)); + [status, msg] = copyfile (from, fileandpath, 1); + if (status == 0) + error (msg); + endif + else + fclose (fid); + endif + system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), + [], FUNCTION.MODE); + return; endif endif - if (isempty (host)) - FUNCTION.EMAIL = " "; - else - FUNCTION.EMAIL = cstrcat ("<", default_user(0), "@", host, ">"); - endif - endif - ## Fill in the revision string. - now = localtime (time); - revs = cstrcat ("Created: ", strftime ("%Y-%m-%d", now)); + ## If editing a new file that is neither a m-file or an oct-file, + ## just edit it. + fileandpath = file; + idx = rindex (file, "."); + name = file(1:idx-1); + ext = file(idx+1:end); + switch (ext) + case {"cc", "m"} + 0; + otherwise + system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), + [], FUNCTION.MODE); + return; + endswitch - ## Fill in the copyright string. - copyright = cstrcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR); - - ## Fill in the author tag field. - author = cstrcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL); + ## The file doesn't exist in path so create it, put in the function + ## template and edit it. - ## Fill in the header. - uclicense = toupper (FUNCTION.LICENSE); - switch (uclicense) - case "GPL" - head = cstrcat (copyright, "\n\n", "\ -This program is free software; you can redistribute it and/or modify\n\ -it under the terms of the GNU General Public License as published by\n\ -the Free Software Foundation; either version 3 of the License, or\n\ -(at your option) any later version.\n\ -\n\ -This program is distributed in the hope that it will be useful,\n\ -but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ -GNU General Public License for more details.\n\ -\n\ -You should have received a copy of the GNU General Public License\n\ -along with Octave; see the file COPYING. If not, see\n\ -<http://www.gnu.org/licenses/>.\ -"); - tail = cstrcat (author, "\n", revs); + ## Guess the email name if it was not given. + if (isempty (FUNCTION.EMAIL)) + host = getenv ("HOSTNAME"); + if (isempty (host) && ispc ()) + host = getenv ("COMPUTERNAME"); + endif + if (isempty (host)) + [status, host] = system ("uname -n"); + ## trim newline from end of hostname + if (! isempty (host)) + host = host(1:end-1); + endif + endif + if (isempty (host)) + FUNCTION.EMAIL = " "; + else + FUNCTION.EMAIL = cstrcat ("<", default_user(0), "@", host, ">"); + endif + endif + + ## Fill in the revision string. + now = localtime (time); + revs = cstrcat ("Created: ", strftime ("%Y-%m-%d", now)); - case "BSD" - head = cstrcat (copyright, "\n\n", "\ -This program is free software; redistribution and use in source and\n\ -binary forms, with or without modification, are permitted provided that\n\ -the following conditions are met:\n\ -\n\ - 1.Redistributions of source code must retain the above copyright\n\ - notice, this list of conditions and the following disclaimer.\n\ - 2.Redistributions in binary form must reproduce the above copyright\n\ - notice, this list of conditions and the following disclaimer in the\n\ - documentation and/or other materials provided with the distribution.\n\ -\n\ -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\ -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\ -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\ -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\ -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\ -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\ -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\ -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\ -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\ -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\ -SUCH DAMAGE.\ -"); - tail = cstrcat (author, "\n", revs); + ## Fill in the copyright string. + copyright = cstrcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR); + + ## Fill in the author tag field. + author = cstrcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL); + + ## Fill in the header. + uclicense = toupper (FUNCTION.LICENSE); + switch (uclicense) + case "GPL" + head = cstrcat (copyright, "\n\n", "\ + This program is free software; you can redistribute it and/or modify\n\ + it under the terms of the GNU General Public License as published by\n\ + the Free Software Foundation; either version 3 of the License, or\n\ + (at your option) any later version.\n\ + \n\ + This program is distributed in the hope that it will be useful,\n\ + but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ + GNU General Public License for more details.\n\ + \n\ + You should have received a copy of the GNU General Public License\n\ + along with Octave; see the file COPYING. If not, see\n\ + <http://www.gnu.org/licenses/>.\ + "); + tail = cstrcat (author, "\n", revs); - case "PD" - head = ""; - tail = cstrcat (author, "\n", revs, "\n\n", - "This program is granted to the public domain."); + case "BSD" + head = cstrcat (copyright, "\n\n", "\ + This program is free software; redistribution and use in source and\n\ + binary forms, with or without modification, are permitted provided that\n\ + the following conditions are met:\n\ + \n\ + 1.Redistributions of source code must retain the above copyright\n\ + notice, this list of conditions and the following disclaimer.\n\ + 2.Redistributions in binary form must reproduce the above copyright\n\ + notice, this list of conditions and the following disclaimer in the\n\ + documentation and/or other materials provided with the distribution.\n\ + \n\ + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\ + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\ + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\ + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\ + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\ + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\ + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\ + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\ + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\ + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\ + SUCH DAMAGE.\ + "); + tail = cstrcat (author, "\n", revs); - otherwise - head = ""; - tail = cstrcat (copyright, "\n\n", FUNCTION.LICENSE, "\n", - author, "\n", revs); - endswitch + case "PD" + head = ""; + tail = cstrcat (author, "\n", revs, "\n\n", + "This program is granted to the public domain."); + + otherwise + head = ""; + tail = cstrcat (copyright, "\n\n", FUNCTION.LICENSE, "\n", + author, "\n", revs); + endswitch - ## Generate the function template. - exists = exist (name); - switch (ext) - case {"cc", "C", "cpp"} - if (isempty (head)) - comment = cstrcat ("/*\n", tail, "\n\n*/\n\n"); - else - comment = cstrcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n"); - endif - ## If we are shadowing an m-file, paste the code for the m-file. - if (any (exists == [2, 103])) - code = cstrcat ("\\ ", strrep (type (name){1}, "\n", "\n// ")); - else - code = " "; - endif - body = cstrcat ("#include <octave/oct.h>\n\n", - "DEFUN_DLD(", name, ",args,nargout,\"\\\n", - name, "\\n\\\n\")\n{\n", - " octave_value_list retval;\n", - " int nargin = args.length ();\n\n", - code, "\n return retval;\n}\n"); + ## Generate the function template. + exists = exist (name); + switch (ext) + case {"cc", "C", "cpp"} + if (isempty (head)) + comment = cstrcat ("/*\n", tail, "\n\n*/\n\n"); + else + comment = cstrcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n"); + endif + ## If we are shadowing an m-file, paste the code for the m-file. + if (any (exists == [2, 103])) + code = cstrcat ("\\ ", strrep (type (name){1}, "\n", "\n// ")); + else + code = " "; + endif + body = cstrcat ("#include <octave/oct.h>\n\n", + "DEFUN_DLD(", name, ",args,nargout,\"\\\n", + name, "\\n\\\n\")\n{\n", + " octave_value_list retval;\n", + " int nargin = args.length ();\n\n", + code, "\n return retval;\n}\n"); - text = cstrcat (comment, body); - case "m" - ## If we are editing a function defined on the fly, paste the - ## code. - if (any (exists == [2, 103])) - body = type (name){1}; - else - body = cstrcat ("function [ ret ] = ", name, " ()\n\nendfunction\n"); - endif - if (isempty (head)) - comment = cstrcat ("## ", name, "\n\n", - "## ", strrep (tail, "\n", "\n## "), "\n\n"); - else - comment = cstrcat ("## ", strrep (head,"\n","\n## "), "\n\n", ... - "## ", name, "\n\n", ... - "## ", strrep (tail, "\n", "\n## "), "\n\n"); - endif - text = cstrcat (comment, body); - endswitch + text = cstrcat (comment, body); + case "m" + ## If we are editing a function defined on the fly, paste the + ## code. + if (any (exists == [2, 103])) + body = type (name){1}; + else + body = cstrcat ("function [ ret ] = ", name, " ()\n\nendfunction\n"); + endif + if (isempty (head)) + comment = cstrcat ("## ", name, "\n\n", + "## ", strrep (tail, "\n", "\n## "), "\n\n"); + else + comment = cstrcat ("## ", strrep (head,"\n","\n## "), "\n\n", ... + "## ", name, "\n\n", ... + "## ", strrep (tail, "\n", "\n## "), "\n\n"); + endif + text = cstrcat (comment, body); + endswitch - ## Write the initial file (if there is anything to write) - fid = fopen (fileandpath, "wt"); - if (fid < 0) - error ("edit: could not create %s", fileandpath); + ## Write the initial file (if there is anything to write) + fid = fopen (fileandpath, "wt"); + if (fid < 0) + error ("edit: could not create %s", fileandpath); + endif + fputs (fid, text); + fclose (fid); + + ## Finally we are ready to edit it! + system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), + [], FUNCTION.MODE); + endif - fputs (fid, text); - fclose (fid); - - ## Finally we are ready to edit it! - system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")), - [], FUNCTION.MODE); endfunction
--- a/scripts/miscellaneous/info.m +++ b/scripts/miscellaneous/info.m @@ -27,8 +27,9 @@ Additional information about GNU Octave is available at\n\ http://www.octave.org\n\ \n\ - Descriptions of mailing lists devoted to Octave are available at\n\ - http://www.octave.org/archive.html\n\ + Links to the mailing list and other resources for getting help with\n\ + Octave are available at\n\ + http://www.octave.org/support.html\n\ \n\ You may also find some information in the Octave Wiki at\n\ http://wiki.octave.org\n\
--- a/scripts/miscellaneous/license.m +++ b/scripts/miscellaneous/license.m @@ -138,10 +138,10 @@ elseif (strcmp (varargin{3}, "disable")) __octave_licenses__{found,3} = false; else - error ("license: TOGGLE must be either `enable' or `disable'"); + error ("license: TOGGLE must be either 'enable' or 'disable'"); endif else - error ("license: FEATURE `%s' not found", feature); + error ("license: FEATURE '%s' not found", feature); endif endif @@ -182,6 +182,6 @@ %% Test input validation %!error license ("not_inuse") %!error <TOGGLE must be either> license ("test", "Octave", "not_enable") -%!error <FEATURE `INVALID' not found> license ("test", "INVALID", "enable") +%!error <FEATURE 'INVALID' not found> license ("test", "INVALID", "enable") %!error license ("not_test", "Octave", "enable")
--- a/scripts/miscellaneous/mkoctfile.m +++ b/scripts/miscellaneous/mkoctfile.m @@ -87,18 +87,18 @@ ## CFLAGS LD_CXX ## CPICFLAG LD_STATIC_FLAG ## CPPFLAGS LFLAGS -## CXX LIBCRUFT -## CXXFLAGS LIBOCTAVE -## CXXPICFLAG LIBOCTINTERP -## DEPEND_EXTRA_SED_PATTERN LIBS -## DEPEND_FLAGS OCTAVE_LIBS -## DL_LD OCTAVE_LINK_DEPS -## DL_LDFLAGS OCT_LINK_DEPS -## EXEEXT RDYNAMIC_FLAG -## F77 READLINE_LIBS -## F77_INTEGER_8_FLAG SED -## FFLAGS XTRA_CFLAGS -## FFTW3_LDFLAGS XTRA_CXXFLAGS +## CXX LIBOCTAVE +## CXXFLAGS LIBOCTINTERP +## CXXPICFLAG LIBS +## DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS +## DEPEND_FLAGS OCTAVE_LINK_DEPS +## DL_LD OCT_LINK_DEPS +## DL_LDFLAGS RDYNAMIC_FLAG +## EXEEXT READLINE_LIBS +## F77 SED +## F77_INTEGER_8_FLAG XTRA_CFLAGS +## FFLAGS XTRA_CXXFLAGS +## FFTW3_LDFLAGS ## FFTW3_LIBS ## FFTW3F_LDFLAGS ## @@ -160,7 +160,7 @@ endif if (sys == 127) - warning ("unable to find mkoctfile in expected location: `%s'", + warning ("unable to find mkoctfile in expected location: '%s'", shell_script); warning ("mkoctfile exited with failure status");
--- a/scripts/miscellaneous/recycle.m +++ b/scripts/miscellaneous/recycle.m @@ -48,7 +48,7 @@ elseif (strcmpi (state, "off")) current_state = "off"; else - error ("recycle: invalid value of STATE = `%s'", state); + error ("recycle: invalid value of STATE = '%s'", state); endif else error ("recycle: STATE must be a character string");
--- a/scripts/miscellaneous/rmappdata.m +++ b/scripts/miscellaneous/rmappdata.m @@ -30,16 +30,30 @@ endif for nh = 1:numel (h) - appdata = get (h(nh), "__appdata__"); - appdata = rmfield (appdata, varargin); - set (h(nh), "__appdata__", appdata); + if (isprop (h(nh), "__appdata__")) + appdata = get (h(nh), "__appdata__"); + for v = 1:numel(varargin) + if (isfield (appdata, varargin{v})) + appdata = rmfield (appdata, varargin{v}); + else + error ("rmappdata: appdata '%s' is not present") + endif + endfor + set (h(nh), "__appdata__", appdata); + endif endfor endfunction - %!test %! setappdata (0, "hello", "world"); %! rmappdata (0, "hello"); %! assert (isappdata (0, "hello"), false); +%!test +%! setappdata (0, "data1", rand (3)); +%! setappdata (0, "data2", {"hello", "world"}); +%! rmappdata (0, "data1", "data2"); +%! assert (isappdata (0, "data1"), false); +%! assert (isappdata (0, "data2"), false); +
--- a/scripts/miscellaneous/tempdir.m +++ b/scripts/miscellaneous/tempdir.m @@ -33,7 +33,7 @@ endif if (! isdir (dirname)) - warning ("tempdir: `%s' does not exist or is not a directory", dirname); + warning ("tempdir: '%s' does not exist or is not a directory", dirname); endif endfunction
--- a/scripts/optimization/fminsearch.m +++ b/scripts/optimization/fminsearch.m @@ -103,7 +103,7 @@ ## maximization.) Default is 1, maximization. ## set STOPIT(6)=-1 for minimization ## If a non-empty fourth parameter string SAVIT is present, then -## `SAVE SAVIT x fmax nf' is executed after each inner iteration. +## 'SAVE SAVIT x fmax nf' is executed after each inner iteration. ## NB: x0 can be a matrix. In the output argument, in SAVIT saves, ## and in function calls, x has the same shape as x0. ## NMSMAX(fun, x0, STOPIT, SAVIT, P1, P2,...) allows additional @@ -257,7 +257,7 @@ ## One step of the Nelder-Mead simplex algorithm ## NJH: Altered function calls and changed CNT to NF. - ## Changed each `fr < f(1)' type test to `>' for maximization + ## Changed each 'fr < f(1)' type test to '>' for maximization ## and re-ordered function values after sort. vbar = (sum (V(:,1:n)')/n)'; # Mean value
--- a/scripts/optimization/optimset.m +++ b/scripts/optimization/optimset.m @@ -121,7 +121,7 @@ try retval = feval (fcn, "defaults"); catch - error ("optimset: no defaults for function `%s'", fcn); + error ("optimset: no defaults for function '%s'", fcn); end_try_catch elseif (nargs == 2 && isstruct (varargin{1}) && isstruct (varargin{2})) ## Set slots in old from nonempties in new. Should we be checking
--- a/scripts/pkg/private/fix_depends.m +++ b/scripts/pkg/private/fix_depends.m @@ -41,7 +41,7 @@ sub = dep(lpar(1)+1:rpar(1)-1); parts = strsplit (sub, " ", true); if (length (parts) != 2) - error ("incorrect syntax for dependency `%s' in the DESCRIPTION file\n", + error ("incorrect syntax for dependency '%s' in the DESCRIPTION file\n", dep); endif operator = parts{1};
--- a/scripts/pkg/private/get_description.m +++ b/scripts/pkg/private/get_description.m @@ -51,7 +51,7 @@ value = strtrim (line (colon+1:end)); if (length (value) == 0) fclose (fid); - error ("The keyword `%s' of the package `%s' has an empty value", + error ("The keyword '%s' of the package '%s' has an empty value", keyword, desc.name); endif desc.(keyword) = value;
--- a/scripts/plot/__gnuplot_drawnow__.m +++ b/scripts/plot/__gnuplot_drawnow__.m @@ -74,7 +74,7 @@ else new_stream = false; endif - term = gnuplot_default_term (); + term = gnuplot_default_term (plot_stream); if (strcmp (term, "dumb")) ## popen2 eats stdout of gnuplot, use temporary file instead dumb_tmp_file = tmpnam (); @@ -114,7 +114,7 @@ ## When "term" originates from print.m, it may include other options. if (nargin < 4) ## This supports the gnuplot graphics toolkit. - term = gnuplot_default_term (); + term = gnuplot_default_term (plot_stream); opts_str = ""; else ## Get the one word terminal id and save the remaining as options to @@ -132,7 +132,7 @@ if (strfind (opts_str, "noenhanced")) enhanced = false; else - enhanced = gnuplot_is_enhanced_term (term); + enhanced = gnuplot_is_enhanced_term (plot_stream, term); endif ## Set the terminal. @@ -329,10 +329,10 @@ endfunction -function term = gnuplot_default_term () +function term = gnuplot_default_term (plot_stream) term = getenv ("GNUTERM"); ## If not specified, guess the terminal type. - if (isempty (term)) + if (isempty (term) || ! __gnuplot_has_terminal__ (term, plot_stream)) if (ismac ()) term = "aqua"; elseif (! isunix ()) @@ -358,24 +358,24 @@ endif endfunction -function have_enhanced = gnuplot_is_enhanced_term (term) +function have_enhanced = gnuplot_is_enhanced_term (plot_stream, term) persistent enhanced_terminals; if (isempty (enhanced_terminals)) ## Don't include pstex, pslatex or epslatex here as the TeX commands ## should not be interpreted in that case. enhanced_terminals = {"aqua", "canvas", "dumb", "emf", "gif", "jpeg", ... "pdf", "pdfcairo", "pm", "png", "pngcairo", ... - "postscript", "svg", "windows", "wxt", "x11"}; + "postscript", "qt", "svg", "windows", "wxt", "x11"}; endif - if (nargin < 1) + if (nargin < 2) ## Determine the default gnuplot terminal. - term = gnuplot_default_term (); + term = gnuplot_default_term (plot_stream); endif have_enhanced = any (strncmp (enhanced_terminals, term, min (numel (term), 3))); endfunction function ret = output_to_screen (term) - ret = any (strcmpi ({"aqua", "dumb", "wxt", "x11", "windows", "pm"}, term)); + ret = any (strcmpi ({"aqua", "dumb", "pm", "qt", "windows", "wxt", "x11"}, term)); endfunction function retval = have_non_legend_axes (h)
--- a/scripts/plot/area.m +++ b/scripts/plot/area.m @@ -18,26 +18,37 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} area (@var{x}, @var{y}) -## @deftypefnx {Function File} {} area (@var{x}, @var{y}, @var{lvl}) +## @deftypefn {Function File} {} area (@var{y}) +## @deftypefnx {Function File} {} area (@var{x}, @var{y}) +## @deftypefnx {Function File} {} area (@dots{}, @var{lvl}) ## @deftypefnx {Function File} {} area (@dots{}, @var{prop}, @var{val}, @dots{}) -## @deftypefnx {Function File} {} area (@var{y}, @dots{}) ## @deftypefnx {Function File} {} area (@var{h}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} area (@dots{}) -## Area plot of cumulative sum of the columns of @var{y}. This shows the -## contributions of a value to a sum, and is functionally similar to +## Area plot of the columns of @var{y}. This shows the +## contributions of each column value to the row sum. It is functionally similar to ## @code{plot (@var{x}, cumsum (@var{y}, 2))}, except that the area under ## the curve is shaded. ## -## If the @var{x} argument is omitted it is assumed to be given by +## If the @var{x} argument is omitted it defaults to ## @code{1 : rows (@var{y})}. A value @var{lvl} can be defined that determines -## where the base level of the shading under the curve should be defined. +## where the base level of the shading under the curve should be defined. The +## default level is 0. ## -## Additional arguments to the @code{area} function are passed to -## @code{patch}. +## Additional arguments to the @code{area} function are passed directly to +## @code{patch}. ## ## The optional return value @var{h} is a graphics handle to the hggroup -## object representing the area patch objects. +## object representing the area patch objects. The "BaseValue" property +## of the hggroup can be used to adjust the level where shading begins. +## +## Example: Verify identity sin^2 + cos^2 = 1 +## +## @example +## t = linspace (0, 2*pi, 100)'; +## y = [sin(t).^2, cos(t).^2)]; +## area (t, y); +## legend ('sin^2', 'cos^2', 'location', 'NorthEastOutside'); +## @end example ## @seealso{plot, patch} ## @end deftypefn @@ -45,60 +56,60 @@ [ax, varargin, nargin] = __plt_get_axis_arg__ ("area", varargin{:}); - if (nargin > 0) - idx = 1; - x = y = []; - bv = 0; - args = {}; - ## Check for (X) or (X,Y) arguments and possible base value. - if (nargin >= idx && ismatrix (varargin{idx})) - y = varargin{idx}; - idx++; - if (nargin >= idx) - if (isscalar (varargin{idx})) + if (nargin == 0) + print_usage (); + endif + + idx = 1; + x = y = []; + bv = 0; + args = {}; + ## Check for (X) or (X,Y) arguments and possible base value. + if (nargin >= idx && ismatrix (varargin{idx})) + y = varargin{idx}; + idx++; + if (nargin >= idx) + if (isscalar (varargin{idx})) + bv = varargin{idx}; + idx++; + elseif (ismatrix (varargin{idx})) + x = y; + y = varargin{idx}; + idx++; + if (nargin >= idx && isscalar (varargin{idx})) bv = varargin{idx}; idx++; - elseif (ismatrix (varargin{idx})) - x = y; - y = varargin{idx}; - idx++; - if (nargin >= idx && isscalar (varargin{idx})) - bv = varargin{idx}; - idx++; - endif endif endif - else - print_usage (); - endif - ## Check for additional args. - if (nargin >= idx) - args = {varargin{idx:end}}; - endif - newplot (); - if (isvector (y)) - y = y(:); - endif - if (isempty (x)) - x = repmat ([1:rows(y)]', 1, columns (y)); - elseif (isvector (x)) - x = repmat (x(:), 1, columns (y)); - endif - - oldax = gca (); - unwind_protect - axes (ax); - tmp = __area__ (ax, x, y, bv, args{:}); - unwind_protect_cleanup - axes (oldax); - end_unwind_protect - - if (nargout > 0) - h = tmp; endif else print_usage (); endif + ## Check for additional args. + if (nargin >= idx) + args = {varargin{idx:end}}; + endif + newplot (); + if (isvector (y)) + y = y(:); + endif + if (isempty (x)) + x = repmat ([1:rows(y)]', 1, columns (y)); + elseif (isvector (x)) + x = repmat (x(:), 1, columns (y)); + endif + + oldax = gca (); + unwind_protect + axes (ax); + tmp = __area__ (ax, x, y, bv, args{:}); + unwind_protect_cleanup + axes (oldax); + end_unwind_protect + + if (nargout > 0) + h = tmp; + endif endfunction @@ -157,9 +168,9 @@ function update_props (h, d) kids = get (h, "children"); set (kids, "edgecolor", get (h, "edgecolor"), - "linewidth", get (h, "linewidth"), - "linestyle", get (h, "linestyle"), - "facecolor", get (h, "facecolor")); + "linewidth", get (h, "linewidth"), + "linestyle", get (h, "linestyle"), + "facecolor", get (h, "facecolor")); endfunction function move_baseline (h, d) @@ -206,3 +217,26 @@ y0 = y1; endfor endfunction + + +%!demo +%! # Verify identity sin^2 + cos^2 = 1 +%! clf; +%! t = linspace (0, 2*pi, 100)'; +%! y = [sin(t).^2, cos(t).^2]; +%! area (t, y); +%! legend ('sin^2', 'cos^2', 'location', 'NorthEastOutside'); + +%!demo +%! # Show effects of setting BaseValue +%! clf; +%! x = [-2:0.1:2]'; +%! y = x.^2 - 1; +%! subplot (1, 2, 1) +%! area (x, y); +%! title ({'Parabola y = x^2 -1';'BaseValue = 0'}); +%! subplot (1, 2, 2) +%! h = area (x, y); +%! set (h, 'basevalue', -1); +%! title ({'Parabola y = x^2 -1';'BaseValue = -1'}); +
--- a/scripts/plot/bar.m +++ b/scripts/plot/bar.m @@ -95,5 +95,15 @@ endfunction -%% FIXME: Need demo or test for function +%!demo +%! clf; +%! y = rand (10, 1); +%! bar (y); +%!demo +%! clf; +%! h = bar (rand (5, 3)); +%! set (h(1), 'facecolor', 'r') +%! set (h(2), 'facecolor', 'g') +%! set (h(3), 'facecolor', 'b') +
--- a/scripts/plot/barh.m +++ b/scripts/plot/barh.m @@ -54,5 +54,15 @@ endfunction -%% FIXME: Need demo or test for function +%!demo +%! clf; +%! x = rand (10, 1); +%! barh (x); +%!demo +%! clf; +%! h = barh (rand (5, 3)); +%! set (h(1), 'facecolor', 'r') +%! set (h(2), 'facecolor', 'g') +%! set (h(3), 'facecolor', 'b') +
--- a/scripts/plot/closereq.m +++ b/scripts/plot/closereq.m @@ -30,7 +30,7 @@ if (nargin == 0) cf = gcbf (); if (isempty (cf)) - warning ("closereq: calling closereq from octave prompt is not supported, use `close' instead"); + warning ("closereq: calling closereq from octave prompt is not supported, use 'close' instead"); cf = get (0, "currentfigure"); endif if (! isempty (cf) && isfigure (cf))
--- a/scripts/plot/colstyle.m +++ b/scripts/plot/colstyle.m @@ -81,7 +81,7 @@ %!test %! [l, c, m, msg] = colstyle ("~"); -%! assert (msg, "colstyle: unrecognized format character: `~'"); +%! assert (msg, "colstyle: unrecognized format character: '~'"); %% Test input validation %!error colstyle ()
--- a/scripts/plot/copyobj.m +++ b/scripts/plot/copyobj.m @@ -95,7 +95,7 @@ %! 'HorizontAlalignment', 'Center', 'Rotation', 30); %! hnew = copyobj (hdl); -%!test +%!testif HAVE_MAGICK %! h1 = figure (); %! set (h1, "visible", "off"); %! x = 0:0.1:2*pi;
--- a/scripts/plot/gco.m +++ b/scripts/plot/gco.m @@ -40,6 +40,6 @@ function h = gco () - h = get (gcf (), "currentobject"); + h = get (get (0, "currentfigure"), "currentobject"); endfunction
--- a/scripts/plot/legend.m +++ b/scripts/plot/legend.m @@ -26,13 +26,14 @@ ## @deftypefnx {Function File} {} legend (@var{hobjs}, @dots{}) ## @deftypefnx {Function File} {} legend (@var{hax}, @var{hobjs}, @dots{}) ## @deftypefnx {Function File} {} legend ("@var{option}") +## @deftypefnx {Function File} {[@var{hleg}, @var{hleg_obj}, @var{hplot}, @var{labels}] =} legend (@dots{}) ## ## Display a legend for the axes with handle @var{hax}, or the current axes, ## using the specified strings as labels. Legend entries may be specified ## as individual character string arguments, a character array, or a cell ## array of character strings. If the handles, @var{hobjs}, are not specified ## then the legend's strings will be associated with the axes' descendants. -## Legend works on line graphs, bar graphs, etc. +## @code{legend} works on line graphs, bar graphs, etc. ## A plot must exist before legend is called. ## ## The optional parameter @var{pos} specifies the location of the legend @@ -74,8 +75,8 @@ ## @end multitable ## ## The optional parameter @var{orient} determines if the key elements -## are placed vertically or horizontally. The allowed values are "vertical" -## or "horizontal" with the default being "vertical". +## are placed vertically or horizontally. The allowed values are +## "vertical" (default) or "horizontal". ## ## The following customizations are available using @var{option}: ## @@ -96,14 +97,35 @@ ## Hide the box around legend ## ## @item "left" -## Place text to the left of the keys +## Place label text to the left of the keys ## ## @item "right" -## Place text to the right of the keys +## Place label text to the right of the keys ## ## @itemx "off" ## Delete the legend object ## @end table +## +## The optional output values are +## +## @table @var +## @item hleg +## The graphics handle of the legend object. +## +## @item hleg_obj +## Graphics handles to the text and line objects which make up the legend. +## +## @item hplot +## Graphics handles to the plot objects which were used in making the legend. +## +## @item labels +## A cell array of strings of the labels in the legend. +## @end table +## +## The legend label text is either provided in the call to @code{legend} or +## is taken from the DisplayName property of graphics objects. If no +## labels or DisplayNames are available, then the label text is simply +## "data1", "data2", @dots{}, "dataN". ## @end deftypefn function [hlegend2, hobjects2, hplot2, text_strings2] = legend (varargin) @@ -122,6 +144,7 @@ ca = gca (); endif + ## Special handling for plotyy which has two axes objects if (ishandle (ca) && isprop (ca, "__plotyy_axes__")) plty = get (ca, "__plotyy_axes__"); if (isscalar (plty) && ishandle (plty)) @@ -135,7 +158,7 @@ endif ## Remove duplicates while preserving order [~, n] = unique (ca); - ca = ca (sort (n)); + ca = ca(sort (n)); endif if (nargin > 0 && all (ishandle (varargin{1}))) @@ -143,7 +166,7 @@ varargin(1) = []; else kids = ca; - kids (strcmp (get (ca, "tag"), "legend")) = []; + kids(strcmp (get (ca, "tag"), "legend")) = []; if (isscalar (kids)) kids = get (kids, "children")(:); else @@ -159,6 +182,7 @@ textpos = "default"; box = "default"; + ## Process old way of specifying position with a number rather than a string. if (nargs > 0) pos = varargin{nargs}; if (isnumeric (pos) && isscalar (pos) && pos == fix (pos)) @@ -172,13 +196,14 @@ endif endif + ## Find position and orientation property/value pairs while (nargs > 1) pos = varargin{nargs-1}; str = varargin{nargs}; - if (strcmpi (pos, "location") && ischar (str)) + if (strcmpi (pos, "location") && ischar (str)) position = lower (str); nargs -= 2; - elseif (strcmpi (pos, "orientation") && ischar (str)) + elseif (strcmpi (pos, "orientation") && ischar (str)) orientation = lower (str); nargs -= 2; else @@ -188,12 +213,12 @@ ## Validate the orientation switch (orientation) - case {"vertical", "horizontal","default"} + case {"vertical", "horizontal", "default"} otherwise error ("legend: unrecognized legend orientation"); endswitch - ## Validate the position type is valid + ## Validate the position type outside = false; inout = strfind (position, "outside"); if (! isempty (inout)) @@ -213,14 +238,15 @@ error ("legend: unrecognized legend position"); endswitch + ## Find any existing legend object on figure hlegend = []; fkids = get (fig, "children"); for i = 1 : numel (fkids) - if (ishandle (fkids (i)) && strcmp (get (fkids (i), "type"), "axes") - && (strcmp (get (fkids (i), "tag"), "legend"))) - udata = get (fkids (i), "userdata"); + if (ishandle (fkids(i)) && strcmp (get (fkids(i), "type"), "axes") + && (strcmp (get (fkids(i), "tag"), "legend"))) + udata = get (fkids(i), "userdata"); if (! isempty (intersect (udata.handle, ca))) - hlegend = fkids (i); + hlegend = fkids(i); break; endif endif @@ -230,19 +256,27 @@ arg = varargin{1}; if (ischar (arg)) if (rows (arg) == 1) - str = tolower (deblank (arg)); + str = tolower (strtrim (arg)); switch (str) - case {"off"} + case "off" delete (hlegend); - return - case {"hide"} + return; + case "hide" show = "off"; nargs--; case "show" - show = "on"; + if (! isempty (hlegend)) + show = "on"; + else + show = "create"; + textpos = "left"; + endif nargs--; case "toggle" - if (isempty (hlegend) || strcmp (get (hlegend, "visible"), "off")) + if (isempty (hlegend)) + show = "create"; + textpos = "left"; + elseif (strcmp (get (hlegend, "visible"), "off")) show = "on"; else show = "off"; @@ -260,23 +294,27 @@ case "right" textpos = "right"; nargs--; - otherwise endswitch else + ## Character matrix of labels varargin = cellstr (arg); nargs = numel (varargin); endif elseif (iscellstr (arg)) + ## Cell array of labels varargin = arg; nargs = numel (varargin); else error ("legend: expecting argument to be a character string"); endif elseif (nargs > 1 && iscellstr (varargin{1})) + ## Cell array of labels followed by property/value pairs varargin = {varargin{1}{:}, varargin{2:end}}; nargs = numel (varargin); endif + have_labels = (nargs > 0); + if (strcmp (show, "off")) if (! isempty (hlegend)) set (findobj (hlegend), "visible", "off"); @@ -297,14 +335,15 @@ endif elseif (strcmp (box, "on")) if (! isempty (hlegend)) - set (hlegend, "visible", "on", "box", "on"); + set (hlegend, "box", "on", "visible", "on"); endif elseif (strcmp (box, "off")) if (! isempty (hlegend)) set (hlegend, "box", "off", "visible", "off"); endif - elseif (nargs == 0 && !(strcmp (position, "default") && - strcmp (orientation, "default"))) + elseif (! have_labels && !(strcmp (position, "default") && + strcmp (orientation, "default"))) + ## Changing location or orientation of existing legend if (! isempty (hlegend)) hax = getfield (get (hlegend, "userdata"), "handle"); [hplots, text_strings] = __getlegenddata__ (hlegend); @@ -329,13 +368,16 @@ endif endif else + ## Create new legend hobjects = []; hplots = []; text_strings = {}; - if (nargs > 0) + if (have_labels) + ## Check for valid data that can be labeled. have_data = false; - for k = 1:nkids + have_dname = false; + for k = 1 : nkids typ = get (kids(k), "type"); if (strcmp (typ, "line") || strcmp (typ, "surface") || strcmp (typ, "patch") || strcmp (typ, "hggroup")) @@ -347,11 +389,40 @@ if (! have_data) warning ("legend: plot data is empty; setting key labels has no effect"); endif - endif + else + ## No labels. Search for DisplayName property. + have_dname = false; + for k = 1 : nkids + hkid = kids(k); + typ = get (hkid, "type"); + if (strcmp (typ, "line") || strcmp (typ, "surface") + || strcmp (typ, "patch")) + if (! isempty (get (hkid, "displayname"))) + have_dname = true; + break; + endif + elseif (strcmp (typ, "hggroup")) + hgkids = get (hkid, "children"); + for j = 1 : length (hgkids) + hgobj = get (hgkids(j)); + if (isfield (hgobj, "displayname") && ! isempty (hgobj.displayname)) + have_dname = true; + break; # break from j-loop over hgkids + endif + endfor + if (have_dname) + break; # break from k loop over nkids + endif + endif # elseif hggroup + endfor # for loop k = 1 : nkids + endif # else branch of if (have_labels) - if (strcmp (textpos, "default")) - warned = false; + if (have_labels || ! have_dname) k = nkids; + if (! have_labels) + varargin = arrayfun (@(x) sprintf ("data%d", x), [1:nkids]', "uniformoutput", false); + nargs = nkids; + endif for i = 1 : nargs arg = varargin{i}; if (ischar (arg)) @@ -365,16 +436,20 @@ if (strcmp (get (kids(k), "type"), "hggroup")) hgkids = get (kids(k), "children"); for j = 1 : length (hgkids) - hgobj = get (hgkids (j)); + hgobj = get (hgkids(j)); if (isfield (hgobj, "displayname")) - set (hgkids(j), "displayname", arg); + if (have_labels) + set (hgkids(j), "displayname", arg); + endif hplots = [hplots, hgkids(j)]; text_strings = {text_strings{:}, arg}; break; endif endfor else - set (kids(k), "displayname", arg); + if (have_labels) + set (kids(k), "displayname", arg); + endif hplots = [hplots, kids(k)]; text_strings = {text_strings{:}, arg}; endif @@ -382,17 +457,18 @@ if (--k == 0) break; endif - elseif (! warned) - break; + else + break; # k = 0, no further handles to process endif else error ("legend: expecting argument to be a character string"); endif endfor - if (i < nargs && ! warned) + if (have_labels && i < nargs) warning ("legend: ignoring extra labels"); endif else + ## No labels specified but objects have DisplayName property set. k = nkids; while (k > 0) typ = get (kids(k), "type"); @@ -409,7 +485,7 @@ if (strcmp (get (kids(k), "type"), "hggroup")) hgkids = get (kids(k), "children"); for j = 1 : length (hgkids) - hgobj = get (hgkids (j)); + hgobj = get (hgkids(j)); if (isfield (hgobj, "displayname") && ! isempty (hgobj.displayname)) hplots = [hplots, hgkids(j)]; @@ -418,9 +494,9 @@ endif endfor else - if (! isempty (get (kids (k), "displayname"))) + if (! isempty (get (kids(k), "displayname"))) hplots = [hplots, kids(k)]; - text_strings = {text_strings{:}, get(kids (k), "displayname")}; + text_strings = {text_strings{:}, get(kids(k), "displayname")}; endif endif if (--k == 0) @@ -433,7 +509,7 @@ if (isempty (hplots)) if (! isempty (hlegend)) fkids = get (fig, "children"); - delete (fkids (fkids == hlegend)); + delete (fkids(fkids == hlegend)); hlegend = []; hobjects = []; hplots = []; @@ -524,24 +600,24 @@ maxheight = 0; for k = 1 : nentries if (strcmp (textpos, "right")) - texthandle = [texthandle, text(0, 0, text_strings {k}, + texthandle = [texthandle, text(0, 0, text_strings{k}, "horizontalalignment", "left", "userdata", hplots(k), "fontsize", ca_fontsize)]; else - texthandle = [texthandle, text(0, 0, text_strings {k}, + texthandle = [texthandle, text(0, 0, text_strings{k}, "horizontalalignment", "right", "userdata", hplots(k), "fontsize", ca_fontsize)]; endif - units = get (texthandle (end), "units"); + units = get (texthandle(end), "units"); unwind_protect - set (texthandle (end), "units", "points"); - extents = get (texthandle (end), "extent"); - maxwidth = max (maxwidth, extents (3)); - maxheight = max (maxheight, extents (4)); + set (texthandle(end), "units", "points"); + extents = get (texthandle(end), "extent"); + maxwidth = max (maxwidth, extents(3)); + maxheight = max (maxheight, extents(4)); unwind_protect_cleanup - set (texthandle (end), "units", units); + set (texthandle(end), "units", units); end_unwind_protect endfor @@ -549,24 +625,24 @@ if (strcmp (orientation, "vertical")) height = nentries * (ypad + maxheight); if (outside) - if (height > ca_pos (4)) + if (height > ca_pos(4)) ## Avoid shrinking the height of the axis to zero if outside num1 = ca_pos(4) / (maxheight + ypad) / 2; endif else - if (height > 0.9 * ca_pos (4)) + if (height > 0.9 * ca_pos(4)) num1 = 0.9 * ca_pos(4) / (maxheight + ypad); endif endif else width = nentries * (ypad + maxwidth); if (outside) - if (width > ca_pos (3)) + if (width > ca_pos(3)) ## Avoid shrinking the width of the axis to zero if outside num1 = ca_pos(3) / (maxwidth + ypad) / 2; endif else - if (width > 0.9 * ca_pos (3)) + if (width > 0.9 * ca_pos(3)) num1 = 0.9 * ca_pos(3) / (maxwidth + ypad); endif endif @@ -683,7 +759,7 @@ xk = 0; yk = 0; for k = 1 : numel (hplots) - hobjects = [hobjects, texthandle (k)]; + hobjects = [hobjects, texthandle(k)]; switch (get (hplots(k), "type")) case "line" color = get (hplots(k), "color"); @@ -724,7 +800,7 @@ "ydata", (lpos(4) - yoffset - [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4), "facecolor", facecolor, "edgecolor", edgecolor, "cdata", cdata, - "userdata", hplots (k)); + "userdata", hplots(k)); hobjects = [hobjects, p1]; endif case "surface" @@ -753,16 +829,16 @@ "xliminclude", "off", "yliminclude", "off"); set (t1, "deletefcn", {@deletelegend1, hlegend}); - ## Resize the axis the legend is attached to if the - ## legend is "outside" the plot and create listener to + ## Resize the axis that the legend is attached to if the + ## legend is "outside" the plot and create a listener to ## resize axis to original size if the legend is deleted, - ## hidden or shown + ## hidden, or shown. if (outside) for i = 1 : numel (ca) units = get (ca(i), "units"); unwind_protect set (ca(i), "units", "points"); - set (ca (i), "position", new_pos); + set (ca(i), "position", new_pos); unwind_protect_cleanup set (ca(i), "units", units); end_unwind_protect @@ -875,7 +951,7 @@ function deletelegend1 (h, d, ca) if (ishandle (ca) && strcmp (get (ca, "type"), "axes") - && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")) + && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off")) && strcmp (get (ca, "beingdeleted"), "off")) delete (ca); endif @@ -884,7 +960,7 @@ function deletelegend2 (h, d, ca, pos, outpos, t1, hplots) for i = 1 : numel (ca) if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes") - && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")) + && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off")) && strcmp (get (ca(i), "beingdeleted"), "off")) if (!isempty (pos) && !isempty(outpos)) units = get (ca(i), "units"); @@ -900,14 +976,14 @@ set (t1, "deletefcn", ""); delete (t1); for i = 1 : numel (hplots) - if (strcmp (get (hplots (i), "type"), "line")) - dellistener (hplots (i), "color"); - dellistener (hplots (i), "linestyle"); - dellistener (hplots (i), "marker"); - dellistener (hplots (i), "markeredgecolor"); - dellistener (hplots (i), "markerfacecolor"); - dellistener (hplots (i), "markersize"); - dellistener (hplots (i), "displayname"); + if (ishandle (hplots(i)) && strcmp (get (hplots (i), "type"), "line")) + dellistener (hplots(i), "color"); + dellistener (hplots(i), "linestyle"); + dellistener (hplots(i), "marker"); + dellistener (hplots(i), "markeredgecolor"); + dellistener (hplots(i), "markerfacecolor"); + dellistener (hplots(i), "markersize"); + dellistener (hplots(i), "displayname"); endif endfor endfunction @@ -917,12 +993,12 @@ ll = []; kids = get (hlegend, "children"); for i = 1 : numel (kids) - if (get (kids (i), "userdata") == h + if (get (kids(i), "userdata") == h && strcmp (get (kids(i), "type"), "line")) if (strcmp (get (kids (i), "marker"), "none")) - ll = kids (i); + ll = kids(i); else - lm = kids (i); + lm = kids(i); endif endif endfor @@ -938,7 +1014,7 @@ ## legend function to recreate a new legend [hplots, text_strings] = __getlegenddata__ (hlegend); for i = 1 : numel (hplots) - if (hplots (i) == h) + if (hplots(i) == h) hplots(i) = []; text_strings(i) = []; break; @@ -986,39 +1062,22 @@ endif endfunction -%!demo -%! plot (rand (2)) -%! legend ({'foo'}, 'bar', 'boxoff') -%! title ('legend() should warn about an extra label') - -%!demo -%! plot (rand (2,2)) ; -%! h = legend ('a', 'b') ; -%! legend ('right') ; -%! set (h, 'textposition', 'left') -%! set (h, 'textposition', 'right') -%! set (h, 'textcolor', [1 0 1]) %!demo -%! clf; -%! x = 0:1; -%! plot (x,x,';I am Blue;', x,2*x,';I am Green;', x,3*x,';I am Red;'); -%! legend boxon -%! legend hide -%! legend show +%! plot (rand (2)); +%! title ('legend called with cellstr and string inputs for labels'); +%! legend ({'foo'}, 'bar'); %!demo -%! clf; -%! x = 0:1; -%! plot (x, x, ';\alpha;', ... -%! x, 2*x, ';\beta=2\alpha;', ... -%! x, 3*x, ';\gamma=3\alpha;'); +%! plot (rand (3)); +%! title ('legend() without inputs creates default labels'); +%! legend (); %!demo %! clf; %! x = 0:1; %! plot (x,x,';I am Blue;', x,2*x, x,3*x,';I am Red;'); -%! title ('Blue and Green keys, with Green missing'); +%! title ('Blue and Red keys, with Green missing'); %!demo %! clf; @@ -1029,9 +1088,9 @@ %!demo %! clf; %! plot (1:10, 1:10, 1:10, fliplr (1:10)); -%! title ('Legend is hidden') -%! legend ({'I am blue', 'I am green'}, 'location', 'east'); -%! legend hide; +%! title ('Legend with keys in horizontal orientation'); +%! legend ({'I am blue', 'I am green'}, 'location', 'east', 'orientation', 'horizontal'); +%! legend boxoff; %!demo %! clf; @@ -1043,21 +1102,55 @@ %!demo %! clf; %! plot (1:10, 1:10, 1:10, fliplr (1:10)); -%! title ('Legend with text to the right'); +%! title ('Legend with text to the right of key'); %! legend ({'I am blue', 'I am green'}, 'location', 'east'); %! legend right; %!demo %! clf; +%! plot (1:10, 1:10, 1:10, fliplr (1:10)); +%! title ('Using properties to have legend text shown to the right of key'); +%! h = legend ({'I am blue', 'I am green'}, 'location', 'east'); +%! legend ('left'); +%! set (h, 'textposition', 'right'); +%! set (h, 'textcolor', [1 0 1]); + +%!demo +%! clf; +%! plot (1:10, 1:10, 1:10, fliplr (1:10)); +%! title ('Legend is hidden') +%! legend ({'I am blue', 'I am green'}, 'location', 'east'); +%! legend hide; + +%!demo +%! clf; +%! x = 0:1; +%! plot (x,x,';I am Blue;', x,2*x,';I am Green;', x,3*x,';I am Red;'); +%! title ('labels embedded in call to plot'); +%! legend boxon +%! legend hide +%! legend show + +%!demo +%! clf; +%! x = 0:1; +%! plot (x, x, ';\alpha;', ... +%! x, 2*x, ';\beta=2\alpha;', ... +%! x, 3*x, ';\gamma=3\alpha;'); +%! title ('labels with interpreted Greek text'); + +%!demo +%! clf; +%! plot (rand (2)); +%! title ('Labels with TeX interpreter turned off'); +%! h = legend ('Hello_World', 'foo^bar'); +%! set (h, 'interpreter', 'none'); + +%!demo +%! clf; %! plot (1:10, 1:10); %! title ('a very long label can sometimes cause problems'); -%! legend ({'hello world'}, 'location', 'northeastoutside'); - -%!demo -%! clf; -%! plot (1:10, 1:10); -%! title ('a very long label can sometimes cause problems'); -%! legend ('hello world', 'location', 'northeastoutside'); +%! legend ('hello very big world', 'location', 'northeastoutside'); %!demo %! clf; @@ -1069,7 +1162,8 @@ %! labels = {labels{:}, ['Signal ', num2str(i)]}; %! end %! hold off; -%! title ('Signals with random offset and uniform noise'); +%! title ({'Signals with random offset and uniform noise'; +%! 'Legend shown below and outside of plot'}); %! xlabel ('Sample Nr [k]'); ylabel ('Amplitude [V]'); %! legend (labels, 'location', 'southoutside'); @@ -1079,6 +1173,7 @@ %! plot (x, x); %! hold on; %! stem (x, x.^2, 'g'); +%! title ('First created object gets first label'); %! legend ('linear'); %! hold off; @@ -1086,12 +1181,14 @@ %! clf; %! x = linspace (0, 10); %! plot (x, x, x, x.^2); +%! title ('First created object gets first label'); %! legend ('linear'); %!demo %! clf; %! x = linspace (0, 10); %! plot (x, x, x, x.^2); +%! title ('Labels are applied in order of object creation'); %! legend ('linear', 'quadratic'); %!demo @@ -1099,6 +1196,7 @@ %! rand_2x3_data1 = [0.341447, 0.171220, 0.284370; 0.039773, 0.731725, 0.779382]; %! bar (rand_2x3_data1); %! ylim ([0 1.0]); +%! title ('legend() works for bar graphs (hgobjects)'); %! legend ({'1st Bar', '2nd Bar', '3rd Bar'}); %!demo @@ -1106,6 +1204,7 @@ %! rand_2x3_data2 = [0.44804, 0.84368, 0.23012; 0.72311, 0.58335, 0.90531]; %! bar (rand_2x3_data2); %! ylim ([0 1.2]); +%! title ('legend() works for bar graphs (hgobjects)'); %! legend ('1st Bar', '2nd Bar', '3rd Bar'); %! legend right; @@ -1123,6 +1222,7 @@ %! hold all; %! plot (x, cos (x), ';cos (x);'); %! hold off; +%! title ('legend constructed from multiple plot calls'); %!demo %! clf; @@ -1131,7 +1231,8 @@ %! hold all; %! plot (x, cos (x), ';cos (x);'); %! hold off; -%! legend ({'sin (x)', 'cos (x)'}, 'location', 'northeastoutside'); +%! title ('Specified label text overrides previous labels'); +%! legend ({'Sine', 'Cosine'}, 'location', 'northeastoutside'); %!demo %! clf; @@ -1139,7 +1240,7 @@ %! plot (x, rand (11)); %! xlabel ('Indices'); %! ylabel ('Random Values'); -%! title ('Legend ''off'' should delete the legend'); +%! title ('Legend ''off'' deletes the legend'); %! legend (cellstr (num2str ((1:10)')), 'location', 'northeastoutside'); %! legend off; %! axis ([0, 10, 0 1]); @@ -1163,21 +1264,15 @@ %!demo %! clf; %! plot (rand (2)); -%! title ('Warn of extra labels'); +%! title ('legend() will warn if extra labels are specified'); %! legend ('Hello', 'World', 'interpreter', 'foobar'); %!demo -%! clf; -%! plot (rand (2)); -%! title ('Turn off TeX interpreter'); -%! h = legend ('Hello_World', 'foo^bar'); -%! set (h, 'interpreter', 'none'); - -%!demo %! x = 0:10; %! y1 = rand (size (x)); %! y2 = rand (size (x)); %! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! title ('plotyy legend test #1: Blue and Green labels'); %! legend ([h1, h2], {'Blue', 'Green'}, 'location', 'south'); %!demo @@ -1185,6 +1280,7 @@ %! y1 = rand (size (x)); %! y2 = rand (size (x)); %! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! title ('plotyy legend test #2: Blue and Green labels'); %! legend ({'Blue', 'Green'}, 'location', 'south'); %!demo @@ -1192,5 +1288,6 @@ %! y1 = rand (size (x)); %! y2 = rand (size (x)); %! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! title ('plotyy legend test #3: Blue and Green labels'); %! legend ('Blue', 'Green', 'location', 'south');
--- a/scripts/plot/print.m +++ b/scripts/plot/print.m @@ -21,19 +21,19 @@ ## @deftypefnx {Function File} {} print (@var{options}) ## @deftypefnx {Function File} {} print (@var{filename}, @var{options}) ## @deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options}) -## Print a graph, or save it to a file. Both output formatted for +## Print a plot, or save it to a file. Both output formatted for ## printing (PDF and PostScript), and many bitmapped and vector ## image formats are supported. ## -## @var{h} specifies the figure handle. If no handle is specified -## the handle for the current figure is used. -## ## @var{filename} defines the name of the output file. If the ## file name has no suffix, one is inferred from the specified ## device and appended to the file name. If no filename is ## specified, the output is sent to the printer. ## -## For output to a printer, to a PostScript file, or a PDF file, +## @var{h} specifies the figure handle. If no handle is specified +## the handle for the current figure is used. +## +## For output to a printer, PostScript file, or PDF file, ## the paper size is specified by the figure's @code{papersize} ## property. The location and size of the image on the page are ## specified by the figure's @code{paperposition} property. The @@ -43,19 +43,19 @@ ## The width and height of images are specified by the figure's ## @code{paperpositon(3:4)} property values. ## -## The @code{print} command supports several @var{options}: +## The @code{print} command supports many @var{options}: ## ## @table @code ## @item -f@var{h} ## Specify the handle, @var{h}, of the figure to be printed. The -## default is the current figure. +## default is the current figure. ## ## @item -P@var{printer} -## Set the @var{printer} name to which the graph is sent if no -## @var{filename} is specified. +## Set the @var{printer} name to which the plot is sent if no +## @var{filename} is specified. ## ## @item -G@var{ghostscript_command} -## Specify the command for calling Ghostscript. For Unix and Windows, +## Specify the command for calling Ghostscript. For Unix and Windows ## the defaults are 'gs' and 'gswin32c', respectively. ## ## @item -color @@ -64,7 +64,7 @@ ## ## @item -solid ## @itemx -dashed -## Forces all lines to be solid or dashed, respectively. +## Force all lines to be solid or dashed, respectively. ## ## @item -portrait ## @itemx -landscape @@ -81,11 +81,11 @@ ## For bitmap and printer output anti-aliasing is applied using ## Ghostscript's TextAlphaBits and GraphicsAlphaBits options. ## The default number of bits for each is 4. -## Allowed values, for @var{N}, are 1, 2, or 4. +## Allowed values for @var{N} are 1, 2, or 4. ## ## @item -d@var{device} ## The available output format is specified by the option @var{device}, -## and is one of: +## and is one of: ## ## @table @code ## @item ps @@ -93,7 +93,7 @@ ## @itemx psc ## @itemx psc2 ## Postscript (level 1 and 2, mono and color). The FLTK graphics -## toolkit generates Postscript level 3.0. +## toolkit generates Postscript level 3.0. ## ## @item eps ## @itemx eps2 @@ -108,7 +108,7 @@ ## @itemx pstex ## @itemx pslatex ## @itemx pdflatex -## Generate a @LaTeX{} (or @TeX{}) file for labels, and eps/ps/pdf +## Generate a @LaTeX{} (or @TeX{}) file for labels and eps/ps/pdf ## for graphics. The file produced by @code{epslatexstandalone} can be ## processed directly by @LaTeX{}. The other formats are intended to ## be included in a @LaTeX{} (or @TeX{}) document. The @code{tex} device @@ -116,8 +116,8 @@ ## is only available for the FLTK graphics toolkit. ## ## @item tikz -## Generate a @LaTeX{} file using PGF/TikZ@. For the FLTK the result is -## PGF. +## Generate a @LaTeX{} file using PGF/TikZ@. For the FLTK toolkit +## the result is PGF. ## ## @item ill ## @itemx aifm @@ -136,9 +136,9 @@ ## ## @item fig ## XFig. For the Gnuplot graphics toolkit, the additional options -## @option{-textspecial} or @option{-textnormal} can be used to control -## whether the special flag should be set for the text in -## the figure (default is @option{-textnormal}). +## @option{-textspecial} or @option{-textnormal} can be used to control +## whether the special flag should be set for the text in +## the figure. (default is @option{-textnormal}) ## ## @item hpgl ## HP plotter language @@ -208,52 +208,52 @@ ## the figure's "paperposition" property. ## ## @itemx -append -## Appends the PS, or PDF output to a pre-existing file of the +## Append Postscript or PDF output to a pre-existing file of the ## same type. ## ## @itemx -r@var{NUM} ## Resolution of bitmaps in pixels per inch. For both metafiles and -## SVG the default is the screen resolution, for other it is 150 dpi. +## SVG the default is the screen resolution; for other formats it is 150 dpi. ## To specify screen resolution, use "-r0". ## ## @item -tight -## Forces a tight bounding box for eps-files. +## Force a tight bounding box for eps files. ## ## @item -@var{preview} -## Adds a preview to eps-files. Supported formats are; +## Add a preview to eps files. Supported formats are: ## ## @table @code ## @item -interchange -## Provides an interchange preview. +## Provide an interchange preview. ## ## @item -metalfile -## Provides a metafile preview. +## Provide a metafile preview. ## ## @item -pict -## Provides pict preview. +## Provide pict preview. ## ## @item -tiff -## Provides a tiff preview. +## Provide a tiff preview. ## @end table ## ## @item -S@var{xsize},@var{ysize} -## Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG@. For +## Plot size in pixels for EMF, GIF, JPEG, PBM, PNG, and SVG@. For ## PS, EPS, PDF, and other vector formats the plot size is in points. ## This option is equivalent to changing the size of the plot box -## associated with "paperposition" property. Using the command form of -## the print function, you must quote the @var{xsize},@var{ysize} -## option. For example, by writing @w{@code{"-S640,480"}}. +## associated with the "paperposition" property. When using the command form +## of the print function you must quote the @var{xsize},@var{ysize} +## option. For example, by writing @w{"-S640,480"}. ## ## @item -F@var{fontname} ## @itemx -F@var{fontname}:@var{size} ## @itemx -F:@var{size} -## Associates all text with the @var{fontname} and/or @var{fontsize}. -## @var{fontname} is ignored for some devices; dxf, fig, hpgl, etc. +## Use @var{fontname} and/or @var{fontsize} for all text. +## @var{fontname} is ignored for some devices: dxf, fig, hpgl, etc. ## @end table ## ## The filename and options can be given in any order. ## -## Example: Print to a file, using the svg device. +## Example: Print to a file using the svg device. ## ## @example ## @group
--- a/scripts/plot/private/__bar__.m +++ b/scripts/plot/private/__bar__.m @@ -217,7 +217,8 @@ if (i == 1) x_axis_range = get (ax, "xlim"); - h_baseline = line (x_axis_range, [0, 0], "color", [0, 0, 0]); + h_baseline = line (x_axis_range, [base_value, base_value], + "color", [0, 0, 0]); set (h_baseline, "handlevisibility", "off"); set (h_baseline, "xliminclude", "off"); addlistener (ax, "xlim", @update_xlim); @@ -230,7 +231,8 @@ addproperty ("basevalue", hg, "data", base_value); addproperty ("baseline", hg, "data", h_baseline); - addlistener (hg, "showbaseline", @show_baseline); + addlistener (hg, "showbaseline", {@show_baseline, "showbl"}); + addlistener (hg, "visible", {@show_baseline, "visib"}); addlistener (hg, "basevalue", @move_baseline); addproperty ("barwidth", hg, "data", width); @@ -316,20 +318,27 @@ endfor endfunction -function show_baseline (h, d) +function show_baseline (h, d, prop = "") persistent recursion = false; - + ## Don't allow recursion if (! recursion) unwind_protect recursion = true; hlist = get (h, "bargroup"); - showbaseline = get (h, "showbaseline"); - for hh = hlist(:)' - if (hh != h) - set (hh, "showbaseline", showbaseline); + if (strcmp (prop, "showbl")) + showbaseline = get (h, "showbaseline"); + for hh = hlist(:)' + if (hh != h) + set (hh, "showbaseline", showbaseline); + endif + endfor + elseif (strcmp (prop, "visib")) + showbaseline = "on"; + if (all (strcmp (get (hlist, "visible"), "off"))) + showbaseline = "off"; endif - endfor + endif set (get (h, "baseline"), "visible", showbaseline); unwind_protect_cleanup recursion = false;
--- a/scripts/plot/private/__contour__.m +++ b/scripts/plot/private/__contour__.m @@ -241,6 +241,8 @@ ## Decode contourc output format. i1 = 1; ncont = 0; + cont_lev = []; + cont_area = []; while (i1 < columns (c)) ncont++; cont_lev(ncont) = c(1, i1);
--- a/scripts/plot/private/__fltk_print__.m +++ b/scripts/plot/private/__fltk_print__.m @@ -61,7 +61,7 @@ endif else error ("print:invalid-suffix", - "invalid suffix `%s' for device `%s'.", + "invalid suffix '%s' for device '%s'.", opts.name(dot:end), lower (opts.devopt)); endif gl2ps_device = {sprintf("%snotxt", lower (suffix))};
--- a/scripts/plot/private/__gnuplot_print__.m +++ b/scripts/plot/private/__gnuplot_print__.m @@ -76,7 +76,7 @@ name = opts.name(1:dot-1); else error ("print:invalid-suffix", - "invalid suffix `%s' for device `%s'.", + "invalid suffix '%s' for device '%s'.", opts.name(dot:end), lower (opts.devopt)); endif endif
--- a/scripts/plot/private/__go_draw_axes__.m +++ b/scripts/plot/private/__go_draw_axes__.m @@ -47,7 +47,7 @@ else h = axis_obj.__plotyy_axes__; h = h(ishandle (h)); - h = h(isprop (h, "__ploty_axes__")); + h = h(isprop (h, "__plotyy_axes__")); rmappdata (h, "__plotyy_axes__"); endif endif @@ -442,6 +442,16 @@ obj = get (kids(end)); + if (isfield (obj, "xdata")) + obj.xdata = double (obj.xdata); + end + if (isfield (obj, "ydata")) + obj.ydata = double (obj.ydata); + end + if (isfield (obj, "zdata")) + obj.zdata = double (obj.zdata); + end + if (isfield (obj, "units")) units = obj.units; unwind_protect
--- a/scripts/plot/private/__go_draw_figure__.m +++ b/scripts/plot/private/__go_draw_figure__.m @@ -199,7 +199,7 @@ fflush (plot_stream); endif else - error ("__go_draw_figure__: expecting figure object, found `%s'", + error ("__go_draw_figure__: expecting figure object, found '%s'", htype); endif else
--- a/scripts/plot/private/__pie__.m +++ b/scripts/plot/private/__pie__.m @@ -139,7 +139,7 @@ text(xt, yt, labels{i}, "horizontalalignment", align)]; else - error ("__pie__: unknown caller `%s'", caller); + error ("__pie__: unknown caller '%s'", caller); endif endfor
--- a/scripts/plot/private/__pltopt__.m +++ b/scripts/plot/private/__pltopt__.m @@ -219,7 +219,7 @@ endif else if (err_on_invalid) - error ("%s: unrecognized format character: `%s'", caller, topt); + error ("%s: unrecognized format character: '%s'", caller, topt); else valid = false; options = __default_plot_options__ ();
--- a/scripts/plot/private/__print_parse_opts__.m +++ b/scripts/plot/private/__print_parse_opts__.m @@ -157,7 +157,7 @@ elseif (length (arg) > 2 && arg(1:2) == "-f") arg_st.figure = str2num (arg(3:end)); elseif (length (arg) >= 1 && arg(1) == "-") - error ("print: unknown option `%s'", arg); + error ("print: unknown option '%s'", arg); elseif (length (arg) > 0) arg_st.name = arg; endif @@ -500,7 +500,7 @@ persistent data = struct () if (! isfield (data, binary)) - ## Reinitialize when `user_binaries' is present. + ## Reinitialize when 'user_binaries' is present. data.(binary).bin = ""; data.(binary).warn_on_absence = false; endif
--- a/scripts/plot/saveas.m +++ b/scripts/plot/saveas.m @@ -102,6 +102,6 @@ prt_opt = strcat ("-d", tolower (fmt)); - print (filename, prt_opt); + print (fig, filename, prt_opt); endfunction
--- a/scripts/plot/scatter.m +++ b/scripts/plot/scatter.m @@ -19,7 +19,6 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} scatter (@var{x}, @var{y}) ## @deftypefnx {Function File} {} scatter (@var{x}, @var{y}, @var{s}) -## @deftypefnx {Function File} {} scatter (@var{x}, @var{y}, @var{c}) ## @deftypefnx {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c}) ## @deftypefnx {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c}, @var{style}) ## @deftypefnx {Function File} {} scatter (@var{x}, @var{y}, @var{s}, @var{c}, @var{prop}, @var{val})
--- a/scripts/plot/shrinkfaces.m +++ b/scripts/plot/shrinkfaces.m @@ -136,7 +136,7 @@ if (ishandle (p)) ## avoid exceptions set (p, "FaceVertexCData", [], "CData", []); - set (p, "Vertices", v, "Faces", f, "FaceVertxCData", c); + set (p, "Vertices", v, "Faces", f, "FaceVertexCData", c); else nf = struct ("faces", f, "vertices", v, "facevertexcdata", c); endif
--- a/scripts/plot/subplot.m +++ b/scripts/plot/subplot.m @@ -206,7 +206,7 @@ else objpos = get (child, "outerposition"); endif - if (all (objpos == pos) && ! replace_axes) + if (all (abs (objpos - pos) < eps) && ! replace_axes) ## If the new axes are in exactly the same position as an ## existing axes object, use the existing axes. found = true;
--- a/scripts/plot/uigetdir.m +++ b/scripts/plot/uigetdir.m @@ -23,7 +23,7 @@ ## Open a GUI dialog for selecting a directory. If @var{init_path} is not ## given the current working directory is used. @var{dialog_name} may be ## used to customize the dialog title. -## @seealso{uigetfile} +## @seealso{uigetfile, uiputfile} ## @end deftypefn ## Author: Kai Habel @@ -38,7 +38,7 @@ if (! __is_function__ (funcname)) error ("uigetdir: fltk graphics toolkit required"); elseif (! strcmp (defaulttoolkit, "gnuplot")) - warning ("uigetdir: no implementation for toolkit `%s', using `fltk' instead", + warning ("uigetdir: no implementation for toolkit '%s', using 'fltk' instead", defaulttoolkit); endif endif
--- a/scripts/plot/uigetfile.m +++ b/scripts/plot/uigetfile.m @@ -58,6 +58,7 @@ ## and a 2-element vector containing the pixel coordinates. ## Two or more files can be selected when setting the "MultiSelect" key to "on". ## In that case @var{fname} is a cell array containing the files. +## @seealso{uiputfile, uigetdir} ## @end deftypefn ## Author: Kai Habel @@ -72,7 +73,7 @@ if (! __is_function__ (funcname)) error ("uigetfile: fltk graphics toolkit required"); elseif (! strcmp (defaulttoolkit, "gnuplot")) - warning ("uigetfile: no implementation for toolkit `%s', using `fltk' instead", + warning ("uigetfile: no implementation for toolkit '%s', using 'fltk' instead", defaulttoolkit); endif endif
--- a/scripts/plot/uiputfile.m +++ b/scripts/plot/uiputfile.m @@ -49,6 +49,7 @@ ## @var{dialog_name} can be used to customize the dialog title. ## If @var{default_file} is given it is preselected in the GUI dialog. ## If, in addition, a path is given it is also used as current path. +## @seealso{uigetfile, uigetdir} ## @end deftypefn ## Author: Kai Habel @@ -63,7 +64,7 @@ if (! __is_function__ (funcname)) error ("uiputfile: fltk graphics toolkit required"); elseif (! strcmp (defaulttoolkit, "gnuplot")) - warning ("uiputfile: no implementation for toolkit `%s', using `fltk' instead", + warning ("uiputfile: no implementation for toolkit '%s', using 'fltk' instead", defaulttoolkit); endif endif
--- a/scripts/signal/stft.m +++ b/scripts/signal/stft.m @@ -78,7 +78,7 @@ elseif (strcmp (win_type, "rectangle")) win_type = 3; else - error ("stft: unknown window type `%s'", win_type); + error ("stft: unknown window type '%s'", win_type); endif endif else
--- a/scripts/sparse/svds.m +++ b/scripts/sparse/svds.m @@ -288,7 +288,7 @@ %! %!testif HAVE_ARPACK %! s = svds (speye (10)); -%! assert (s, ones (6, 1), 2*eps); +%! assert (s, ones (6, 1), 4*eps); %!test %! ## Restore random number generator seeds at end of tests
--- a/scripts/specfun/perms.m +++ b/scripts/specfun/perms.m @@ -38,35 +38,36 @@ ## @end example ## @end deftypefn -function A = perms (v) +function A = perms (w) if (nargin != 1) print_usage (); endif - v = v(:); + v = [1:length(w)]'; n = length (v); if (n == 0) - A = []; + p = []; else - A = v(1); + p = v(1); for j = 2:n - B = A; - A = zeros (prod (2:j), n, class (v)); + B = p; + p = zeros (prod (2:j), n); k = rows (B); idx = 1:k; for i = j:-1:1 - A(idx,1:i-1) = B(:,1:i-1); - A(idx,i) = v(j); - A(idx,i+1:j) = B(:,i:j-1); + p(idx,1:i-1) = B(:,1:i-1); + p(idx,i) = v(j); + p(idx,i+1:j) = B(:,i:j-1); idx += k; endfor endfor endif + A = w(p); endfunction %!assert (perms ([1,2,3]), [1,2,3;2,1,3;1,3,2;2,3,1;3,1,2;3,2,1]) -%!assert (perms (1:3), perms ([1,2,3])) +%!assert (perms ("abc"), ["abc"; "bac"; "acb"; "bca"; "cab"; "cba"]) %!assert (perms (int8 ([1,2,3])), int8 ([1,2,3;2,1,3;1,3,2;2,3,1;3,1,2;3,2,1])) %!error perms ()
--- a/scripts/statistics/base/mean.m +++ b/scripts/statistics/base/mean.m @@ -113,11 +113,15 @@ if (strcmp (opt, "a")) y = sum (x, dim) / n; elseif (strcmp (opt, "g")) - y = prod (x, dim) .^ (1/n); + if (all (x(:) >= 0)) + y = exp (sum (log (x), dim) ./ n); + else + error ("mean: X must not contain any negative values"); + endif elseif (strcmp (opt, "h")) y = n ./ sum (1 ./ x, dim); else - error ("mean: option `%s' not recognized", opt); + error ("mean: option '%s' not recognized", opt); endif endfunction @@ -131,6 +135,9 @@ %! assert (mean (y), 0); %! assert (mean (z), [0, 10]); +## Test small numbers +%!assert (mean (repmat (0.1,1,1000), "g"), 0.1, 20*eps) + %!assert (mean (magic (3), 1), [5, 5, 5]) %!assert (mean (magic (3), 2), [5; 5; 5]) %!assert (mean ([2 8], "g"), 4)
--- a/scripts/statistics/tests/anova.m +++ b/scripts/statistics/tests/anova.m @@ -50,14 +50,14 @@ print_usage (); elseif (nargin == 1) if (isvector (y)) - error ("anova: for `anova (Y)', Y must not be a vector"); + error ("anova: for 'anova (Y)', Y must not be a vector"); endif [group_count, k] = size (y); n = group_count * k; group_mean = mean (y); else if (! isvector (y)) - error ("anova: for `anova (Y, G)', Y must be a vector"); + error ("anova: for 'anova (Y, G)', Y must be a vector"); endif n = length (y); if (! isvector (g) || (length (g) != n))
--- a/scripts/statistics/tests/cor_test.m +++ b/scripts/statistics/tests/cor_test.m @@ -113,7 +113,7 @@ t.dist = "stdnormal"; cdf = stdnormal_cdf (t.stat); else - error ("cor_test: METHOD `%s' not recognized", method); + error ("cor_test: METHOD '%s' not recognized", method); endif if (strcmp (alt, "!=") || strcmp (alt, "<>")) @@ -123,7 +123,7 @@ elseif (strcmp (alt, "<")) t.pval = cdf; else - error ("cor_test: alternative `%s' not recognized", alt); + error ("cor_test: alternative '%s' not recognized", alt); endif t.alternative = alt;
--- a/scripts/statistics/tests/t_test_regression.m +++ b/scripts/statistics/tests/t_test_regression.m @@ -86,7 +86,7 @@ elseif (strcmp (alt, "<")) pval = cdf; else - error ("t_test_regression: the value `%s' for alt is not possible", alt); + error ("t_test_regression: the value '%s' for alt is not possible", alt); endif if (nargout == 0)
--- a/scripts/strings/strsplit.m +++ b/scripts/strings/strsplit.m @@ -104,7 +104,7 @@ %!assert (strsplit ("road to hell", " "), {"road", "to", "hell"}) %!assert (strsplit ("road to^hell", " ^"), {"road", "to", "hell"}) %!assert (strsplit ("road to--hell", " -", true), {"road", "to", "hell"}) -%!assert (strsplit (["a,bc";",de"], ","), {"a", "bc", ones(1,0), "de "}) +%!assert (strsplit (["a,bc";",de"], ","), {"a", "bc", char(ones(1,0)), "de "}) %!assert (strsplit (["a,bc";",de"], ",", true), {"a", "bc", "de "}) %!assert (strsplit (["a,bc";",de"], ", ", true), {"a", "bc", "de"})
--- a/scripts/testfun/demo.m +++ b/scripts/testfun/demo.m @@ -101,7 +101,11 @@ endif [code, idx] = test (name, "grabdemo"); - if (isempty (idx)) + + if (idx == -1) + warning ("no function %s found", name); + return; + elseif (isempty (idx)) warning ("no demo available for %s", name); return; elseif (n >= length (idx))
--- a/scripts/testfun/test.m +++ b/scripts/testfun/test.m @@ -171,7 +171,7 @@ if (isempty (__file)) if (__grabdemo) __ret1 = ""; - __ret2 = []; + __ret2 = -1; else if (exist (__name) == 3) fprintf (__fid, "%s%s source code with tests for dynamically linked function not found\n", __signal_empty, __name);
--- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,38 +22,17 @@ ## Search local directories before those specified by the user. AM_CPPFLAGS = \ - -I$(srcdir)/../libinterp \ + -I$(top_srcdir)/liboctave/array \ + -I$(top_srcdir)/liboctave/cruft/misc \ + -I$(top_srcdir)/liboctave/numeric \ + -I$(top_srcdir)/liboctave/util \ + -I$(top_srcdir)/libinterp \ + -I$(top_builddir)/libinterp/interpfcn \ -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu -if AMCOND_BUILD_COMPILED_AUX_PROGRAMS -bin_PROGRAMS = \ - mkoctfile \ - $(OCTAVE_PROGRAMS) \ - octave-config - -mkoctfile_SOURCES = -nodist_mkoctfile_SOURCES = mkoctfile.cc -mkoctfile_LDADD = $(top_builddir)/libgnu/libgnu.la $(LIBS) +AM_CFLAGS += $(WARN_CFLAGS) -octave_config_SOURCES = -nodist_octave_config_SOURCES = octave-config.cc -octave_config_LDADD = \ - corefcn/libcorefcn.la \ - $(top_builddir)/libgnu/libgnu.la \ - $(LIBS) - -BUILT_SOURCES_EXTRA = \ - mkoctfile.cc \ - octave-config.cc -else -bin_PROGRAMS = \ - octave \ - octave-cli - -bin_SCRIPTS = \ - mkoctfile \ - octave-config -endif +AM_CXXFLAGS += $(WARN_CXXFLAGS) EXTRA_DIST = \ mkoctfile.in.cc \ @@ -61,12 +40,17 @@ octave-config.in.cc \ octave-config.in.sh +DISTCLEANFILES = + +OCTAVE_BINARIES = \ + octave \ + octave-cli + OCTAVE_CORE_LIBS = \ - ../libinterp/liboctinterp.la \ - ../liboctave/liboctave.la \ - ../libcruft/libcruft.la + $(top_builddir)/libinterp/liboctinterp.la \ + $(top_builddir)/liboctave/liboctave.la -include ../libgui/src/link-deps.mk +include ../libgui/link-deps.mk octave_cli_SOURCES = main-cli.cc @@ -80,7 +64,7 @@ if AMCOND_BUILD_GUI octave_SOURCES = main.cc - OCTAVE_GUI_LIBS = ../libgui/src/liboctgui.la + OCTAVE_GUI_LIBS = $(top_builddir)/libgui/liboctgui.la OCTAVE_GUI_CPPFLAGS = -I$(top_srcdir)/libgui/src else octave_SOURCES = main-cli.cc @@ -102,11 +86,40 @@ $(OCTAVE_GUI_LINK_OPTS) if AMCOND_BUILD_COMPILED_AUX_PROGRAMS +bin_PROGRAMS = \ + $(OCTAVE_BINARIES) \ + mkoctfile \ + octave-config + +mkoctfile_SOURCES = +nodist_mkoctfile_SOURCES = mkoctfile.cc +mkoctfile_LDADD = $(top_builddir)/libgnu/libgnu.la $(LIBS) + +octave_config_SOURCES = +nodist_octave_config_SOURCES = octave-config.cc +octave_config_LDADD = \ + $(top_builddir)/libinterp/corefcn/libcorefcn.la \ + $(top_builddir)/libgnu/libgnu.la \ + $(LIBS) + +DISTCLEANFILES += mkoctfile.cc octave-config.cc + +else +bin_PROGRAMS = \ + $(OCTAVE_BINARIES) + +bin_SCRIPTS = \ + mkoctfile \ + octave-config +endif + +if AMCOND_BUILD_COMPILED_AUX_PROGRAMS octave-config.cc: octave-config.in.cc Makefile @$(do_subst_default_vals) mkoctfile.cc: mkoctfile.in.cc Makefile @$(do_subst_config_vals) + else octave-config: octave-config.in.sh Makefile @$(do_subst_default_vals)
--- a/src/main-cli.cc +++ b/src/main-cli.cc @@ -24,13 +24,16 @@ #include <config.h> #endif -#include <octave.h> +#include "defaults.h" +#include "octave.h" int main (int argc, char **argv) { octave_process_command_line (argc, argv); + install_defaults (); + octave_initialize_interpreter (argc, argv, 0); return octave_execute_interpreter ();
--- a/src/main.cc +++ b/src/main.cc @@ -24,8 +24,9 @@ #include <config.h> #endif -#include <octave.h> -#include <octave-gui.h> +#include "defaults.h" +#include "octave.h" +#include "octave-gui.h" int main (int argc, char **argv) @@ -34,6 +35,8 @@ octave_process_command_line (argc, argv); + install_defaults (); + if (octave_starting_gui ()) retval = octave_start_gui (argc, argv); else
--- a/src/mkoctfile.in.cc +++ b/src/mkoctfile.in.cc @@ -25,6 +25,7 @@ #endif #include <string> +#include <cstring> #include <map> #include <list> #include <algorithm> @@ -48,11 +49,11 @@ static string OCTAVE_VERSION = %OCTAVE_CONF_VERSION%; -static std::string -substitute_prefix (const std::string& s, const std::string& prefix, - const std::string& new_prefix) +static string +substitute_prefix (const string& s, const string& prefix, + const string& new_prefix) { - std::string retval = s; + string retval = s; if (!prefix.empty () && new_prefix != prefix) { @@ -62,7 +63,7 @@ } #if defined (__WIN32__) && ! defined (_POSIX_VERSION) - std::replace (retval.begin (), retval.end (), '/', '\\'); + replace (retval.begin (), retval.end (), '/', '\\'); #endif return retval; @@ -72,7 +73,7 @@ get_line (FILE *fp) { static vector<char> buf (100); - int idx = 0; + unsigned int idx = 0; char c; while (true) @@ -123,7 +124,7 @@ #if defined (__WIN32__) && ! defined (_POSIX_VERSION) int n = 1024; - std::string bin_dir (n, '\0'); + string bin_dir (n, '\0'); while (true) { @@ -154,10 +155,10 @@ vars["OCTAVE_PREFIX"] = %OCTAVE_CONF_PREFIX%; - std::string DEFAULT_OCTINCLUDEDIR = %OCTAVE_CONF_OCTINCLUDEDIR%; - std::string DEFAULT_INCLUDEDIR = %OCTAVE_CONF_INCLUDEDIR%; - std::string DEFAULT_LIBDIR = %OCTAVE_CONF_LIBDIR%; - std::string DEFAULT_OCTLIBDIR = %OCTAVE_CONF_OCTLIBDIR%; + string DEFAULT_OCTINCLUDEDIR = %OCTAVE_CONF_OCTINCLUDEDIR%; + string DEFAULT_INCLUDEDIR = %OCTAVE_CONF_INCLUDEDIR%; + string DEFAULT_LIBDIR = %OCTAVE_CONF_LIBDIR%; + string DEFAULT_OCTLIBDIR = %OCTAVE_CONF_OCTLIBDIR%; if (! vars["OCTAVE_HOME"].empty ()) { @@ -184,18 +185,18 @@ vars["OCTLIBDIR"] = get_variable ("OCTLIBDIR", DEFAULT_OCTLIBDIR); #if defined (__WIN32__) && ! defined (_POSIX_VERSION) - std::string DEFAULT_INCFLAGS + string DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "\\..") + " -I" + quote_path (vars["OCTINCLUDEDIR"]); #else - std::string DEFAULT_INCFLAGS + string DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "/..") + " -I" + quote_path (vars["OCTINCLUDEDIR"]); #endif if (vars["INCLUDEDIR"] != "/usr/include") DEFAULT_INCFLAGS += " -I" + quote_path (vars["INCLUDEDIR"]); - std::string DEFAULT_LFLAGS = "-L" + quote_path (vars["OCTLIBDIR"]); + string DEFAULT_LFLAGS = "-L" + quote_path (vars["OCTLIBDIR"]); if (vars["LIBDIR"] != "/usr/lib") DEFAULT_LFLAGS += " -L" + quote_path (vars["LIBDIR"]); @@ -223,7 +224,6 @@ vars["LIBOCTAVE"] = "-loctave"; vars["LIBOCTINTERP"] = "-loctinterp"; vars["READLINE_LIBS"] = "-lreadline"; - vars["LIBCRUFT"] = "-lcruft"; vars["LAPACK_LIBS"] = get_variable ("LAPACK_LIBS", %OCTAVE_CONF_LAPACK_LIBS%); vars["BLAS_LIBS"] = get_variable ("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%); vars["FFTW3_LDFLAGS"] = get_variable ("FFTW3_LDFLAGS", %OCTAVE_CONF_FFTW3_LDFLAGS%); @@ -254,7 +254,7 @@ + " " + vars["LDFLAGS"]; vars["OCTAVE_LIBS"] = vars["LIBOCTINTERP"] + " " + vars["LIBOCTAVE"] - + " " + vars["SPECIAL_MATH_LIB"] + " " + vars["LIBCRUFT"]; + + " " + vars["SPECIAL_MATH_LIB"]; vars["FFTW_LIBS"] = vars["FFTW3_LDFLAGS"] + " " + vars["FFTW3_LIBS"] + " " + vars["FFTW3F_LDFLAGS"] + " " + vars["FFTW3F_LIBS"]; @@ -307,20 +307,20 @@ " CC LD_CXX\n" " CFLAGS LD_STATIC_FLAG\n" " CPICFLAG LFLAGS\n" -" CPPFLAGS LIBCRUFT\n" -" CXX LIBOCTAVE\n" -" CXXFLAGS LIBOCTINTERP\n" -" CXXPICFLAG LIBS\n" -" DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS\n" -" DEPEND_FLAGS OCTAVE_LINK_DEPS\n" -" DL_LD OCTAVE_LINK_OPTS\n" -" DL_LDFLAGS OCT_LINK_DEPS\n" -" EXEEXT OCT_LINK_OPTS\n" -" F77 RDYNAMIC_FLAG\n" -" F77_INTEGER_8_FLAG READLINE_LIBS\n" -" FFLAGS SED\n" -" FFTW3_LDFLAGS XTRA_CFLAGS\n" -" FFTW3_LIBS XTRA_CXXFLAGS\n" +" CPPFLAGS LIBOCTAVE\n" +" CXX LIBOCTINTERP\n" +" CXXFLAGS LIBS\n" +" CXXPICFLAG OCTAVE_LIBS\n" +" DEPEND_EXTRA_SED_PATTERN OCTAVE_LINK_DEPS\n" +" DEPEND_FLAGS OCTAVE_LINK_OPTS\n" +" DL_LD OCT_LINK_DEPS\n" +" DL_LDFLAGS OCT_LINK_OPTS\n" +" EXEEXT RDYNAMIC_FLAG\n" +" F77 READLINE_LIBS\n" +" F77_INTEGER_8_FLAG SED\n" +" FFLAGS XTRA_CFLAGS\n" +" FFTW3_LDFLAGS XTRA_CXXFLAGS\n" +" FFTW3_LIBS\n" " FFTW3F_LDFLAGS\n" " FFTW3F_LIBS\n" "\n" @@ -353,21 +353,23 @@ static string basename (const string& s, bool strip_path = false) { + string retval; size_t pos = s.rfind ('.'); - string retval; if (pos == string::npos) retval = s; else retval = s.substr (0, pos); + if (strip_path) { size_t p1 = retval.rfind ('/'), p2 = retval.rfind ('\\'); pos = (p1 != string::npos && p2 != string::npos ? max (p1, p2) : (p2 != string::npos ? p2 : p1)); if (pos != string::npos) - retval = retval.substr (0, pos); + retval = retval.substr (++pos, string::npos); } + return retval; } @@ -434,7 +436,6 @@ for (int i = 1; i < argc; i++) { string arg = argv[i]; - size_t len = arg.length (); if (ends_with (arg, ".c")) { @@ -606,13 +607,13 @@ FILE *fd = popen (cmd.c_str (), "r"); ofstream fo (dfile.c_str ()); - int pos; + size_t pos; while (!feof (fd)) { line = get_line (fd); if ((pos = line.rfind (".o:")) != string::npos) { - int spos = line.rfind ('/', pos); + size_t spos = line.rfind ('/', pos); string ofile = (spos == string::npos ? line.substr (0, pos+2) : line.substr (spos+1, pos-spos+1)); fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr (pos) << endl; } @@ -634,13 +635,13 @@ FILE *fd = popen (cmd.c_str (), "r"); ofstream fo (dfile.c_str ()); - int pos; + size_t pos; while (!feof (fd)) { line = get_line (fd); if ((pos = line.rfind (".o:")) != string::npos) { - int spos = line.rfind ('/', pos); + size_t spos = line.rfind ('/', pos); string ofile = (spos == string::npos ? line.substr (0, pos+2) : line.substr (spos+1, pos-spos+1)); fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr (pos+2) << endl; } @@ -751,7 +752,7 @@ + " " + vars["ALL_LDFLAGS"] + " " + pass_on_options + " " + output_option + " " + objfiles + " " + libfiles + " " + ldflags + " " + vars["LFLAGS"] - + " -loctinterp -loctave -lcruft " + + " -loctinterp -loctave " + " " + vars["OCT_LINK_OPTS"] + " " + vars["OCTAVE_LINK_DEPS"]; result = run_command (cmd); @@ -768,7 +769,7 @@ string cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " " + pass_on_options + " -o " + octfile + " " + objfiles + " " + libfiles + " " + ldflags + " " + vars["LFLAGS"] - + " -loctinterp -loctave -lcruft " + + " -loctinterp -loctave " + vars["OCT_LINK_OPTS"] + " " + vars["OCT_LINK_DEPS"]; result = run_command (cmd); }
--- a/src/mkoctfile.in.sh +++ b/src/mkoctfile.in.sh @@ -89,7 +89,6 @@ : ${LIBOCTAVE=-loctave} : ${LIBOCTINTERP=-loctinterp} : ${READLINE_LIBS=-lreadline} -: ${LIBCRUFT=-lcruft} : ${LAPACK_LIBS=%OCTAVE_CONF_LAPACK_LIBS%} : ${BLAS_LIBS=%OCTAVE_CONF_BLAS_LIBS%} : ${FFTW3_LDFLAGS=%OCTAVE_CONF_FFTW3_LDFLAGS%} @@ -116,7 +115,7 @@ : ${ALL_LDFLAGS="$LD_STATIC_FLAG $CPICFLAG $LDFLAGS"} -: ${OCTAVE_LIBS="$LIBOCTINTERP $LIBOCTAVE $SPECIAL_MATH_LIB $LIBCRUFT"} +: ${OCTAVE_LIBS="$LIBOCTINTERP $LIBOCTAVE $SPECIAL_MATH_LIB"} # Local variables. @@ -243,18 +242,18 @@ CFLAGS LD_CXX CPICFLAG LD_STATIC_FLAG CPPFLAGS LFLAGS - CXX LIBCRUFT - CXXFLAGS LIBOCTAVE - CXXPICFLAG LIBOCTINTERP - DEPEND_EXTRA_SED_PATTERN LIBS - DEPEND_FLAGS OCTAVE_LIBS - DL_LD OCTAVE_LINK_DEPS - DL_LDFLAGS OCT_LINK_DEPS - EXEEXT RDYNAMIC_FLAG - F77 READLINE_LIBS - F77_INTEGER_8_FLAG SED - FFLAGS XTRA_CFLAGS - FFTW3_LDFLAGS XTRA_CXXFLAGS + CXX LIBOCTAVE + CXXFLAGS LIBOCTINTERP + CXXPICFLAG LIBS + DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS + DEPEND_FLAGS OCTAVE_LINK_DEPS + DL_LD OCT_LINK_DEPS + DL_LDFLAGS RDYNAMIC_FLAG + EXEEXT READLINE_LIBS + F77 SED + F77_INTEGER_8_FLAG XTRA_CFLAGS + FFLAGS XTRA_CXXFLAGS + FFTW3_LDFLAGS FFTW3_LIBS FFTW3F_LDFLAGS @@ -533,7 +532,7 @@ if $link && [ -n "$objfiles" ]; then if $link_stand_alone; then if [ -n "$LD_CXX" ]; then - cmd="$LD_CXX $CPPFLAGS $ALL_CXXFLAGS $RDYNAMIC_FLAG $ALL_LDFLAGS $pass_on_options $output_option $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave -lcruft $OCTAVE_LINK_OPTS $OCTAVE_LINK_DEPS" + cmd="$LD_CXX $CPPFLAGS $ALL_CXXFLAGS $RDYNAMIC_FLAG $ALL_LDFLAGS $pass_on_options $output_option $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave $OCTAVE_LINK_OPTS $OCTAVE_LINK_DEPS" $dbg $cmd eval $cmd else @@ -541,7 +540,7 @@ exit 1 fi else - cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave -lcruft $OCT_LINK_OPTS $OCT_LINK_DEPS" + cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave $OCT_LINK_OPTS $OCT_LINK_DEPS" $dbg $cmd eval $cmd fi
--- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -# Makefile for octave's test directory +# Makefile for Octave's test directory # # Copyright (C) 1994-2012 John W. Eaton #
--- a/test/nest/module.mk +++ b/test/nest/module.mk @@ -1,6 +1,7 @@ nest_FCN_FILES = \ nest/arg_nest.m \ nest/arg_ret.m \ + nest/nest_eval.m \ nest/no_closure.m \ nest/persistent_nest.m \ nest/recursive_nest.m \
new file mode 100644 --- /dev/null +++ b/test/nest/nest_eval.m @@ -0,0 +1,8 @@ +function x = nest_eval (a, b) + eval (a); + nested (); + + function nested () + eval (b); + endfunction +endfunction
--- a/test/nest/test_nest.m +++ b/test/nest/test_nest.m @@ -47,7 +47,12 @@ %!test %! scope3; +%!assert (nest_eval ("x = 5;", "x = 6;"), 6); +%!assert (nest_eval ("x = 5;", "y = 6;"), 5); +%!assert (nest_eval ("x = -5; x = abs (x);", "y = 6;"), 5); + %!error <D' undefined near line 7> scope2 %!error <handles to nested functions are not yet supported> no_closure (0) %!error <handles to nested functions are not yet supported> no_closure (1) - +%!error <can not add variable "y" to a static workspace> nest_eval ("y = 5;", "") +%!error <can not add variable "y" to a static workspace> nest_eval ("y;", "")
--- a/test/test_eval-catch.m +++ b/test/test_eval-catch.m @@ -32,8 +32,8 @@ %% test/octave.test/eval-catch/eval-catch-5.m %!test %! eval ("clear a; a; str = '';", "str=lasterr;"); -%! assert (lasterr()(1:13), "`a' undefined"); -%! assert (str(1:13), "`a' undefined"); +%! assert (lasterr()(1:13), "'a' undefined"); +%! assert (str(1:13), "'a' undefined"); %% test/octave.test/eval-catch/eval-catch-6.m %!test @@ -48,26 +48,26 @@ %!endfunction %!test %! eval ("clear a; a; str='';", "str = mangle (lasterr);"); -%! assert (mangle(lasterr)(1:14), "<`a' undefined"); -%! assert (str(1:14), "<`a' undefined"); +%! assert (mangle(lasterr)(1:14), "<'a' undefined"); +%! assert (str(1:14), "<'a' undefined"); %% test/octave.test/eval-catch/eval-catch-8.m %!test %! eval ("eval (\"clear a; a;str1='';\", \"str1=lasterr;\"); clear b; b; str2='';", %! "str2 = lasterr;"); -%! assert (str1(1:13), "`a' undefined"); -%! assert (str2(1:13), "`b' undefined"); +%! assert (str1(1:13), "'a' undefined"); +%! assert (str2(1:13), "'b' undefined"); %% test/octave.test/eval-catch/eval-catch-9.m %!test %! eval ("clear a; a; str1='';", %! "eval (\"clear b; b; str2='';\", \"str2=lasterr;\"); str1=lasterr;"); -%! assert (str1(1:13), "`b' undefined"); -%! assert (str2(1:13), "`b' undefined"); +%! assert (str1(1:13), "'b' undefined"); +%! assert (str2(1:13), "'b' undefined"); %% test/octave.test/eval-catch/eval-catch-10.m %!test %! eval ("eval (\"clear a; a; str='';\",\"error (cstrcat (\\\"rethrow: \\\", lasterr));str='';\");", %! "str=lasterr;"); -%! assert (str(1:22), "rethrow: `a' undefined"); +%! assert (str(1:22), "rethrow: 'a' undefined");
--- a/test/test_try.m +++ b/test/test_try.m @@ -63,9 +63,9 @@ %! a; %! error ("Shoudn't get here"); %! catch -%! assert (lasterr()(1:13), "`a' undefined"); +%! assert (lasterr()(1:13), "'a' undefined"); %! end_try_catch -%! assert (lasterr()(1:13), "`a' undefined"); +%! assert (lasterr()(1:13), "'a' undefined"); %% test/octave.test/try/try-6.m %!test @@ -86,7 +86,7 @@ %! a; %! error ("Shoudn't get here"); %! catch -%! assert (mangle (lasterr)(1:14), "<`a' undefined"); +%! assert (mangle (lasterr)(1:14), "<'a' undefined"); %! end_try_catch %% test/octave.test/try/try-8.m @@ -97,13 +97,13 @@ %! a; %! error ("Shoudn't get here"); %! catch -%! assert (lasterr()(1:13), "`a' undefined"); +%! assert (lasterr()(1:13), "'a' undefined"); %! end_try_catch %! clear b; %! b; %! error ("Shoudn't get here"); %! catch -%! assert (lasterr()(1:13), "`b' undefined"); +%! assert (lasterr()(1:13), "'b' undefined"); %! end_try_catch %% test/octave.test/try/try-9.m @@ -114,12 +114,12 @@ %! error ("Shoudn't get here"); %! catch %! try -%! assert (lasterr()(1:13), "`a' undefined"); +%! assert (lasterr()(1:13), "'a' undefined"); %! clear b; %! b; %! error ("Shoudn't get here"); %! catch -%! assert (lasterr()(1:13), "`b' undefined"); +%! assert (lasterr()(1:13), "'b' undefined"); %! end_try_catch %! end_try_catch @@ -134,6 +134,6 @@ %! error (cstrcat ("rethrow: ", lasterr)); %! end_try_catch %! catch -%! assert (lasterr()(1:22), "rethrow: `a' undefined"); +%! assert (lasterr()(1:22), "rethrow: 'a' undefined"); %! end_try_catch