Mercurial > octave
view libinterp/corefcn/oct-stream.cc @ 22755:3a2b891d0b33
maint: Standardize Copyright formatting.
* Makefile.am, README, build-aux/check-subst-vars.in.sh,
build-aux/find-files-with-tests.sh, build-aux/mk-builtins.sh,
build-aux/mk-default-qt-settings.in.sh, build-aux/mk-f77-def.in.sh,
build-aux/mk-hg-id.sh, build-aux/mk-mxarray-h.in.sh,
build-aux/mk-octave-config-h.sh, build-aux/mk-opts.pl,
build-aux/mk-version-h.in.sh, build-aux/subst-config-vals.in.sh,
build-aux/subst-cross-config-vals.in.sh, build-aux/subst-default-vals.in.sh,
build-aux/subst-f77-isnan-macro.in.sh, build-aux/subst-script-vals.in.sh,
configure.ac, doc/interpreter/arith.txi, doc/interpreter/audio.txi,
doc/interpreter/basics.txi, doc/interpreter/bugs.txi,
doc/interpreter/container.txi, doc/interpreter/cp-idx.txi,
doc/interpreter/data.txi, doc/interpreter/debug.txi,
doc/interpreter/diagperm.txi, doc/interpreter/diffeq.txi,
doc/interpreter/errors.txi, doc/interpreter/eval.txi, doc/interpreter/expr.txi,
doc/interpreter/external.txi, doc/interpreter/fn-idx.txi,
doc/interpreter/func.txi, doc/interpreter/genpropdoc.m,
doc/interpreter/geometry.txi, doc/interpreter/geometryimages.m,
doc/interpreter/grammar.txi, doc/interpreter/gui.txi,
doc/interpreter/image.txi, doc/interpreter/install.txi,
doc/interpreter/interp.txi, doc/interpreter/interpimages.m,
doc/interpreter/intro.txi, doc/interpreter/io.txi, doc/interpreter/linalg.txi,
doc/interpreter/macros.texi, doc/interpreter/matrix.txi,
doc/interpreter/mk-doc-cache.pl, doc/interpreter/mkoctfile.1,
doc/interpreter/nonlin.txi, doc/interpreter/numbers.txi,
doc/interpreter/obsolete.txi, doc/interpreter/octave-cli.1,
doc/interpreter/octave-config.1, doc/interpreter/octave.1,
doc/interpreter/octave.css, doc/interpreter/octave.texi,
doc/interpreter/oop.txi, doc/interpreter/op-idx.txi, doc/interpreter/optim.txi,
doc/interpreter/package.txi, doc/interpreter/plot.txi,
doc/interpreter/plotimages.m, doc/interpreter/poly.txi,
doc/interpreter/preface.txi, doc/interpreter/quad.txi, doc/interpreter/set.txi,
doc/interpreter/signal.txi, doc/interpreter/sparse.txi,
doc/interpreter/sparseimages.m, doc/interpreter/splineimages.m,
doc/interpreter/stats.txi, doc/interpreter/stmt.txi,
doc/interpreter/strings.txi, doc/interpreter/system.txi,
doc/interpreter/testfun.txi, doc/interpreter/var.txi,
doc/interpreter/vectorize.txi, doc/liboctave/array.texi,
doc/liboctave/bugs.texi, doc/liboctave/cp-idx.texi, doc/liboctave/dae.texi,
doc/liboctave/diffeq.texi, doc/liboctave/error.texi, doc/liboctave/factor.texi,
doc/liboctave/fn-idx.texi, doc/liboctave/gpl.texi, doc/liboctave/install.texi,
doc/liboctave/intro.texi, doc/liboctave/liboctave.texi,
doc/liboctave/matvec.texi, doc/liboctave/nleqn.texi, doc/liboctave/nlfunc.texi,
doc/liboctave/ode.texi, doc/liboctave/optim.texi, doc/liboctave/preface.texi,
doc/liboctave/quad.texi, doc/liboctave/range.texi, doc/refcard/refcard-a4.tex,
doc/refcard/refcard-legal.tex, doc/refcard/refcard-letter.tex,
doc/refcard/refcard.tex, etc/HACKING, etc/icons/octave.appdata.xml.in,
libgui/graphics/Backend.cc, libgui/graphics/Backend.h,
libgui/graphics/BaseControl.cc, libgui/graphics/BaseControl.h,
libgui/graphics/ButtonControl.cc, libgui/graphics/ButtonControl.h,
libgui/graphics/ButtonGroup.cc, libgui/graphics/ButtonGroup.h,
libgui/graphics/Canvas.cc, libgui/graphics/Canvas.h,
libgui/graphics/CheckBoxControl.cc, libgui/graphics/CheckBoxControl.h,
libgui/graphics/Container.cc, libgui/graphics/Container.h,
libgui/graphics/ContextMenu.cc, libgui/graphics/ContextMenu.h,
libgui/graphics/EditControl.cc, libgui/graphics/EditControl.h,
libgui/graphics/Figure.cc, libgui/graphics/Figure.h,
libgui/graphics/FigureWindow.cc, libgui/graphics/FigureWindow.h,
libgui/graphics/GLCanvas.cc, libgui/graphics/GLCanvas.h,
libgui/graphics/GenericEventNotify.h, libgui/graphics/KeyMap.cc,
libgui/graphics/KeyMap.h, libgui/graphics/ListBoxControl.cc,
libgui/graphics/ListBoxControl.h, libgui/graphics/Logger.cc,
libgui/graphics/Logger.h, libgui/graphics/Menu.cc, libgui/graphics/Menu.h,
libgui/graphics/MenuContainer.h, libgui/graphics/MouseModeActionGroup.cc,
libgui/graphics/MouseModeActionGroup.h, libgui/graphics/Object.cc,
libgui/graphics/Object.h, libgui/graphics/ObjectFactory.cc,
libgui/graphics/ObjectFactory.h, libgui/graphics/ObjectProxy.cc,
libgui/graphics/ObjectProxy.h, libgui/graphics/Panel.cc,
libgui/graphics/Panel.h, libgui/graphics/PopupMenuControl.cc,
libgui/graphics/PopupMenuControl.h, libgui/graphics/PushButtonControl.cc,
libgui/graphics/PushButtonControl.h, libgui/graphics/PushTool.cc,
libgui/graphics/PushTool.h, libgui/graphics/QtHandlesUtils.cc,
libgui/graphics/QtHandlesUtils.h, libgui/graphics/RadioButtonControl.cc,
libgui/graphics/RadioButtonControl.h, libgui/graphics/SliderControl.cc,
libgui/graphics/SliderControl.h, libgui/graphics/TextControl.cc,
libgui/graphics/TextControl.h, libgui/graphics/TextEdit.cc,
libgui/graphics/TextEdit.h, libgui/graphics/ToggleButtonControl.cc,
libgui/graphics/ToggleButtonControl.h, libgui/graphics/ToggleTool.cc,
libgui/graphics/ToggleTool.h, libgui/graphics/ToolBar.cc,
libgui/graphics/ToolBar.h, libgui/graphics/ToolBarButton.cc,
libgui/graphics/ToolBarButton.h, libgui/graphics/__init_qt__.cc,
libgui/graphics/__init_qt__.h, libgui/graphics/annotation-dialog.cc,
libgui/graphics/annotation-dialog.h, libgui/graphics/gl-select.cc,
libgui/graphics/gl-select.h, libgui/src/color-picker.cc,
libgui/src/color-picker.h, libgui/src/dialog.cc, libgui/src/dialog.h,
libgui/src/documentation-dock-widget.cc,
libgui/src/documentation-dock-widget.h, libgui/src/files-dock-widget.cc,
libgui/src/files-dock-widget.h, libgui/src/find-files-dialog.cc,
libgui/src/find-files-dialog.h, libgui/src/find-files-model.cc,
libgui/src/find-files-model.h, libgui/src/history-dock-widget.cc,
libgui/src/history-dock-widget.h, libgui/src/liboctgui-build-info.h,
libgui/src/liboctgui-build-info.in.cc,
libgui/src/m-editor/file-editor-interface.h,
libgui/src/m-editor/file-editor-tab.cc, libgui/src/m-editor/file-editor-tab.h,
libgui/src/m-editor/file-editor.cc, libgui/src/m-editor/file-editor.h,
libgui/src/m-editor/find-dialog.cc, libgui/src/m-editor/find-dialog.h,
libgui/src/m-editor/marker.cc, libgui/src/m-editor/marker.h,
libgui/src/m-editor/octave-qscintilla.cc,
libgui/src/m-editor/octave-qscintilla.h,
libgui/src/m-editor/octave-txt-lexer.cc,
libgui/src/m-editor/octave-txt-lexer.h, libgui/src/main-window.cc,
libgui/src/main-window.h, libgui/src/octave-cmd.cc, libgui/src/octave-cmd.h,
libgui/src/octave-dock-widget.cc, libgui/src/octave-dock-widget.h,
libgui/src/octave-gui.cc, libgui/src/octave-gui.h,
libgui/src/octave-interpreter.cc, libgui/src/octave-interpreter.h,
libgui/src/octave-qt-link.cc, libgui/src/octave-qt-link.h,
libgui/src/qtinfo/parser.cc, libgui/src/qtinfo/parser.h,
libgui/src/qtinfo/webinfo.cc, libgui/src/qtinfo/webinfo.h,
libgui/src/resource-manager.cc, libgui/src/resource-manager.h,
libgui/src/settings-dialog.cc, libgui/src/settings-dialog.h,
libgui/src/shortcut-manager.cc, libgui/src/shortcut-manager.h,
libgui/src/terminal-dock-widget.cc, libgui/src/terminal-dock-widget.h,
libgui/src/thread-manager.cc, libgui/src/thread-manager.h,
libgui/src/welcome-wizard.cc, libgui/src/welcome-wizard.h,
libgui/src/workspace-model.cc, libgui/src/workspace-model.h,
libgui/src/workspace-view.cc, libgui/src/workspace-view.h,
libinterp/build-env.h, libinterp/build-env.in.cc, libinterp/builtins.h,
libinterp/corefcn/Cell.cc, libinterp/corefcn/Cell.h,
libinterp/corefcn/__contourc__.cc, libinterp/corefcn/__dsearchn__.cc,
libinterp/corefcn/__ichol__.cc, libinterp/corefcn/__ilu__.cc,
libinterp/corefcn/__lin_interpn__.cc, libinterp/corefcn/__luinc__.cc,
libinterp/corefcn/__magick_read__.cc, libinterp/corefcn/__pchip_deriv__.cc,
libinterp/corefcn/__qp__.cc, libinterp/corefcn/balance.cc,
libinterp/corefcn/base-text-renderer.h, libinterp/corefcn/besselj.cc,
libinterp/corefcn/betainc.cc, libinterp/corefcn/bitfcns.cc,
libinterp/corefcn/bsxfun.cc, libinterp/corefcn/c-file-ptr-stream.cc,
libinterp/corefcn/c-file-ptr-stream.h, libinterp/corefcn/call-stack.cc,
libinterp/corefcn/call-stack.h, libinterp/corefcn/cdisplay.c,
libinterp/corefcn/cdisplay.h, libinterp/corefcn/cellfun.cc,
libinterp/corefcn/coct-hdf5-types.c, libinterp/corefcn/colloc.cc,
libinterp/corefcn/comment-list.cc, libinterp/corefcn/comment-list.h,
libinterp/corefcn/conv2.cc, libinterp/corefcn/daspk.cc,
libinterp/corefcn/dasrt.cc, libinterp/corefcn/dassl.cc,
libinterp/corefcn/data.cc, libinterp/corefcn/data.h,
libinterp/corefcn/debug.cc, libinterp/corefcn/debug.h,
libinterp/corefcn/defaults.cc, libinterp/corefcn/defaults.in.h,
libinterp/corefcn/defun-dld.h, libinterp/corefcn/defun-int.h,
libinterp/corefcn/defun.cc, libinterp/corefcn/defun.h,
libinterp/corefcn/det.cc, libinterp/corefcn/dirfns.cc,
libinterp/corefcn/dirfns.h, libinterp/corefcn/display.cc,
libinterp/corefcn/display.h, libinterp/corefcn/dlmread.cc,
libinterp/corefcn/dot.cc, libinterp/corefcn/dynamic-ld.cc,
libinterp/corefcn/dynamic-ld.h, libinterp/corefcn/eig.cc,
libinterp/corefcn/ellipj.cc, libinterp/corefcn/error.cc,
libinterp/corefcn/error.h, libinterp/corefcn/errwarn.cc,
libinterp/corefcn/errwarn.h, libinterp/corefcn/event-queue.cc,
libinterp/corefcn/event-queue.h, libinterp/corefcn/fft.cc,
libinterp/corefcn/fft2.cc, libinterp/corefcn/fftn.cc,
libinterp/corefcn/file-io.cc, libinterp/corefcn/file-io.h,
libinterp/corefcn/filter.cc, libinterp/corefcn/find.cc,
libinterp/corefcn/ft-text-renderer.cc, libinterp/corefcn/ft-text-renderer.h,
libinterp/corefcn/gammainc.cc, libinterp/corefcn/gcd.cc,
libinterp/corefcn/getgrent.cc, libinterp/corefcn/getpwent.cc,
libinterp/corefcn/getrusage.cc, libinterp/corefcn/givens.cc,
libinterp/corefcn/gl-render.cc, libinterp/corefcn/gl-render.h,
libinterp/corefcn/gl2ps-print.cc, libinterp/corefcn/gl2ps-print.h,
libinterp/corefcn/graphics.cc, libinterp/corefcn/graphics.in.h,
libinterp/corefcn/gripes.cc, libinterp/corefcn/gripes.h,
libinterp/corefcn/gsvd.cc, libinterp/corefcn/hash.cc,
libinterp/corefcn/help.cc, libinterp/corefcn/help.h, libinterp/corefcn/hess.cc,
libinterp/corefcn/hex2num.cc, libinterp/corefcn/hook-fcn.cc,
libinterp/corefcn/hook-fcn.h, libinterp/corefcn/input.cc,
libinterp/corefcn/input.h, libinterp/corefcn/interpreter.cc,
libinterp/corefcn/interpreter.h, libinterp/corefcn/inv.cc,
libinterp/corefcn/jit-ir.cc, libinterp/corefcn/jit-ir.h,
libinterp/corefcn/jit-typeinfo.cc, libinterp/corefcn/jit-typeinfo.h,
libinterp/corefcn/jit-util.cc, libinterp/corefcn/jit-util.h,
libinterp/corefcn/kron.cc, libinterp/corefcn/load-path.cc,
libinterp/corefcn/load-path.h, libinterp/corefcn/load-save.cc,
libinterp/corefcn/load-save.h, libinterp/corefcn/lookup.cc,
libinterp/corefcn/ls-ascii-helper.cc, libinterp/corefcn/ls-ascii-helper.h,
libinterp/corefcn/ls-hdf5.cc, libinterp/corefcn/ls-hdf5.h,
libinterp/corefcn/ls-mat-ascii.cc, libinterp/corefcn/ls-mat-ascii.h,
libinterp/corefcn/ls-mat4.cc, libinterp/corefcn/ls-mat4.h,
libinterp/corefcn/ls-mat5.cc, libinterp/corefcn/ls-mat5.h,
libinterp/corefcn/ls-oct-binary.cc, libinterp/corefcn/ls-oct-binary.h,
libinterp/corefcn/ls-oct-text.cc, libinterp/corefcn/ls-oct-text.h,
libinterp/corefcn/ls-utils.cc, libinterp/corefcn/ls-utils.h,
libinterp/corefcn/lsode.cc, libinterp/corefcn/lu.cc,
libinterp/corefcn/mappers.cc, libinterp/corefcn/matrix_type.cc,
libinterp/corefcn/max.cc, libinterp/corefcn/mex.cc, libinterp/corefcn/mex.h,
libinterp/corefcn/mexproto.h, libinterp/corefcn/mgorth.cc,
libinterp/corefcn/mxarray.in.h, libinterp/corefcn/nproc.cc,
libinterp/corefcn/oct-errno.h, libinterp/corefcn/oct-errno.in.cc,
libinterp/corefcn/oct-fstrm.cc, libinterp/corefcn/oct-fstrm.h,
libinterp/corefcn/oct-handle.h, libinterp/corefcn/oct-hdf5-types.cc,
libinterp/corefcn/oct-hdf5-types.h, libinterp/corefcn/oct-hdf5.h,
libinterp/corefcn/oct-hist.cc, libinterp/corefcn/oct-hist.h,
libinterp/corefcn/oct-iostrm.cc, libinterp/corefcn/oct-iostrm.h,
libinterp/corefcn/oct-lvalue.cc, libinterp/corefcn/oct-lvalue.h,
libinterp/corefcn/oct-map.cc, libinterp/corefcn/oct-map.h,
libinterp/corefcn/oct-obj.h, libinterp/corefcn/oct-opengl.h,
libinterp/corefcn/oct-prcstrm.cc, libinterp/corefcn/oct-prcstrm.h,
libinterp/corefcn/oct-procbuf.cc, libinterp/corefcn/oct-procbuf.h,
libinterp/corefcn/oct-stdstrm.h, libinterp/corefcn/oct-stream.cc,
libinterp/corefcn/oct-stream.h, libinterp/corefcn/oct-strstrm.cc,
libinterp/corefcn/oct-strstrm.h, libinterp/corefcn/oct-tex-lexer.in.ll,
libinterp/corefcn/oct-tex-parser.in.yy, libinterp/corefcn/oct.h,
libinterp/corefcn/octave-default-image.h, libinterp/corefcn/octave-link.cc,
libinterp/corefcn/octave-link.h,
libinterp/corefcn/octave-preserve-stream-state.h,
libinterp/corefcn/ordschur.cc, libinterp/corefcn/pager.cc,
libinterp/corefcn/pager.h, libinterp/corefcn/pinv.cc,
libinterp/corefcn/pr-output.cc, libinterp/corefcn/pr-output.h,
libinterp/corefcn/procstream.cc, libinterp/corefcn/procstream.h,
libinterp/corefcn/profiler.cc, libinterp/corefcn/profiler.h,
libinterp/corefcn/psi.cc, libinterp/corefcn/pt-jit.cc,
libinterp/corefcn/pt-jit.h, libinterp/corefcn/quad.cc,
libinterp/corefcn/quadcc.cc, libinterp/corefcn/qz.cc,
libinterp/corefcn/rand.cc, libinterp/corefcn/rcond.cc,
libinterp/corefcn/regexp.cc, libinterp/corefcn/schur.cc,
libinterp/corefcn/sighandlers.cc, libinterp/corefcn/sighandlers.h,
libinterp/corefcn/sparse-xdiv.cc, libinterp/corefcn/sparse-xdiv.h,
libinterp/corefcn/sparse-xpow.cc, libinterp/corefcn/sparse-xpow.h,
libinterp/corefcn/sparse.cc, libinterp/corefcn/spparms.cc,
libinterp/corefcn/sqrtm.cc, libinterp/corefcn/str2double.cc,
libinterp/corefcn/strfind.cc, libinterp/corefcn/strfns.cc,
libinterp/corefcn/sub2ind.cc, libinterp/corefcn/svd.cc,
libinterp/corefcn/sylvester.cc, libinterp/corefcn/symtab.cc,
libinterp/corefcn/symtab.h, libinterp/corefcn/syscalls.cc,
libinterp/corefcn/sysdep.cc, libinterp/corefcn/sysdep.h,
libinterp/corefcn/text-renderer.cc, libinterp/corefcn/text-renderer.h,
libinterp/corefcn/time.cc, libinterp/corefcn/toplev.cc,
libinterp/corefcn/toplev.h, libinterp/corefcn/tril.cc,
libinterp/corefcn/tsearch.cc, libinterp/corefcn/txt-eng.cc,
libinterp/corefcn/txt-eng.h, libinterp/corefcn/typecast.cc,
libinterp/corefcn/urlwrite.cc, libinterp/corefcn/utils.cc,
libinterp/corefcn/utils.h, libinterp/corefcn/variables.cc,
libinterp/corefcn/variables.h, libinterp/corefcn/workspace-element.h,
libinterp/corefcn/xdiv.cc, libinterp/corefcn/xdiv.h,
libinterp/corefcn/xnorm.cc, libinterp/corefcn/xnorm.h,
libinterp/corefcn/xpow.cc, libinterp/corefcn/xpow.h,
libinterp/corefcn/zfstream.cc, libinterp/corefcn/zfstream.h,
libinterp/deprecated-config.h, libinterp/dldfcn/__delaunayn__.cc,
libinterp/dldfcn/__eigs__.cc, libinterp/dldfcn/__fltk_uigetfile__.cc,
libinterp/dldfcn/__glpk__.cc, libinterp/dldfcn/__init_fltk__.cc,
libinterp/dldfcn/__init_gnuplot__.cc, libinterp/dldfcn/__osmesa_print__.cc,
libinterp/dldfcn/__voronoi__.cc, libinterp/dldfcn/amd.cc,
libinterp/dldfcn/audiodevinfo.cc, libinterp/dldfcn/audioread.cc,
libinterp/dldfcn/ccolamd.cc, libinterp/dldfcn/chol.cc,
libinterp/dldfcn/colamd.cc, libinterp/dldfcn/convhulln.cc,
libinterp/dldfcn/dmperm.cc, libinterp/dldfcn/fftw.cc, libinterp/dldfcn/gzip.cc,
libinterp/dldfcn/oct-qhull.h, libinterp/dldfcn/qr.cc,
libinterp/dldfcn/symbfact.cc, libinterp/dldfcn/symrcm.cc, libinterp/gendoc.pl,
libinterp/genprops.awk, libinterp/liboctinterp-build-info.h,
libinterp/liboctinterp-build-info.in.cc, libinterp/mk-errno-list,
libinterp/mk-pkg-add, libinterp/mkops, libinterp/octave-value/ov-base-diag.cc,
libinterp/octave-value/ov-base-diag.h, libinterp/octave-value/ov-base-int.cc,
libinterp/octave-value/ov-base-int.h, libinterp/octave-value/ov-base-mat.cc,
libinterp/octave-value/ov-base-mat.h, libinterp/octave-value/ov-base-scalar.cc,
libinterp/octave-value/ov-base-scalar.h,
libinterp/octave-value/ov-base-sparse.cc,
libinterp/octave-value/ov-base-sparse.h, libinterp/octave-value/ov-base.cc,
libinterp/octave-value/ov-base.h, libinterp/octave-value/ov-bool-mat.cc,
libinterp/octave-value/ov-bool-mat.h, libinterp/octave-value/ov-bool-sparse.cc,
libinterp/octave-value/ov-bool-sparse.h, libinterp/octave-value/ov-bool.cc,
libinterp/octave-value/ov-bool.h, libinterp/octave-value/ov-builtin.cc,
libinterp/octave-value/ov-builtin.h, libinterp/octave-value/ov-cell.cc,
libinterp/octave-value/ov-cell.h, libinterp/octave-value/ov-ch-mat.cc,
libinterp/octave-value/ov-ch-mat.h, libinterp/octave-value/ov-class.cc,
libinterp/octave-value/ov-class.h, libinterp/octave-value/ov-classdef.cc,
libinterp/octave-value/ov-classdef.h, libinterp/octave-value/ov-colon.cc,
libinterp/octave-value/ov-colon.h, libinterp/octave-value/ov-complex.cc,
libinterp/octave-value/ov-complex.h, libinterp/octave-value/ov-cs-list.cc,
libinterp/octave-value/ov-cs-list.h, libinterp/octave-value/ov-cx-diag.cc,
libinterp/octave-value/ov-cx-diag.h, libinterp/octave-value/ov-cx-mat.cc,
libinterp/octave-value/ov-cx-mat.h, libinterp/octave-value/ov-cx-sparse.cc,
libinterp/octave-value/ov-cx-sparse.h, libinterp/octave-value/ov-dld-fcn.cc,
libinterp/octave-value/ov-dld-fcn.h, libinterp/octave-value/ov-fcn-handle.cc,
libinterp/octave-value/ov-fcn-handle.h,
libinterp/octave-value/ov-fcn-inline.cc,
libinterp/octave-value/ov-fcn-inline.h, libinterp/octave-value/ov-fcn.cc,
libinterp/octave-value/ov-fcn.h, libinterp/octave-value/ov-float.cc,
libinterp/octave-value/ov-float.h, libinterp/octave-value/ov-flt-complex.cc,
libinterp/octave-value/ov-flt-complex.h,
libinterp/octave-value/ov-flt-cx-diag.cc,
libinterp/octave-value/ov-flt-cx-diag.h,
libinterp/octave-value/ov-flt-cx-mat.cc,
libinterp/octave-value/ov-flt-cx-mat.h,
libinterp/octave-value/ov-flt-re-diag.cc,
libinterp/octave-value/ov-flt-re-diag.h,
libinterp/octave-value/ov-flt-re-mat.cc,
libinterp/octave-value/ov-flt-re-mat.h, libinterp/octave-value/ov-int-traits.h,
libinterp/octave-value/ov-int16.cc, libinterp/octave-value/ov-int16.h,
libinterp/octave-value/ov-int32.cc, libinterp/octave-value/ov-int32.h,
libinterp/octave-value/ov-int64.cc, libinterp/octave-value/ov-int64.h,
libinterp/octave-value/ov-int8.cc, libinterp/octave-value/ov-int8.h,
libinterp/octave-value/ov-intx.h, libinterp/octave-value/ov-java.cc,
libinterp/octave-value/ov-java.h, libinterp/octave-value/ov-lazy-idx.cc,
libinterp/octave-value/ov-lazy-idx.h, libinterp/octave-value/ov-mex-fcn.cc,
libinterp/octave-value/ov-mex-fcn.h, libinterp/octave-value/ov-null-mat.cc,
libinterp/octave-value/ov-null-mat.h, libinterp/octave-value/ov-oncleanup.cc,
libinterp/octave-value/ov-oncleanup.h, libinterp/octave-value/ov-perm.cc,
libinterp/octave-value/ov-perm.h, libinterp/octave-value/ov-range.cc,
libinterp/octave-value/ov-range.h, libinterp/octave-value/ov-re-diag.cc,
libinterp/octave-value/ov-re-diag.h, libinterp/octave-value/ov-re-mat.cc,
libinterp/octave-value/ov-re-mat.h, libinterp/octave-value/ov-re-sparse.cc,
libinterp/octave-value/ov-re-sparse.h, libinterp/octave-value/ov-scalar.cc,
libinterp/octave-value/ov-scalar.h, libinterp/octave-value/ov-str-mat.cc,
libinterp/octave-value/ov-str-mat.h, libinterp/octave-value/ov-struct.cc,
libinterp/octave-value/ov-struct.h, libinterp/octave-value/ov-typeinfo.cc,
libinterp/octave-value/ov-typeinfo.h, libinterp/octave-value/ov-uint16.cc,
libinterp/octave-value/ov-uint16.h, libinterp/octave-value/ov-uint32.cc,
libinterp/octave-value/ov-uint32.h, libinterp/octave-value/ov-uint64.cc,
libinterp/octave-value/ov-uint64.h, libinterp/octave-value/ov-uint8.cc,
libinterp/octave-value/ov-uint8.h, libinterp/octave-value/ov-usr-fcn.cc,
libinterp/octave-value/ov-usr-fcn.h, libinterp/octave-value/ov.cc,
libinterp/octave-value/ov.h, libinterp/octave-value/ovl.cc,
libinterp/octave-value/ovl.h, libinterp/octave.cc, libinterp/octave.h,
libinterp/op-kw-docs, libinterp/operators/op-b-b.cc,
libinterp/operators/op-b-bm.cc, libinterp/operators/op-b-sbm.cc,
libinterp/operators/op-bm-b.cc, libinterp/operators/op-bm-bm.cc,
libinterp/operators/op-bm-sbm.cc, libinterp/operators/op-cdm-cdm.cc,
libinterp/operators/op-cdm-cm.cc, libinterp/operators/op-cdm-cs.cc,
libinterp/operators/op-cdm-dm.cc, libinterp/operators/op-cdm-m.cc,
libinterp/operators/op-cdm-s.cc, libinterp/operators/op-cell.cc,
libinterp/operators/op-chm.cc, libinterp/operators/op-class.cc,
libinterp/operators/op-cm-cdm.cc, libinterp/operators/op-cm-cm.cc,
libinterp/operators/op-cm-cs.cc, libinterp/operators/op-cm-dm.cc,
libinterp/operators/op-cm-m.cc, libinterp/operators/op-cm-pm.cc,
libinterp/operators/op-cm-s.cc, libinterp/operators/op-cm-scm.cc,
libinterp/operators/op-cm-sm.cc, libinterp/operators/op-cs-cm.cc,
libinterp/operators/op-cs-cs.cc, libinterp/operators/op-cs-m.cc,
libinterp/operators/op-cs-s.cc, libinterp/operators/op-cs-scm.cc,
libinterp/operators/op-cs-sm.cc, libinterp/operators/op-dm-cdm.cc,
libinterp/operators/op-dm-cm.cc, libinterp/operators/op-dm-cs.cc,
libinterp/operators/op-dm-dm.cc, libinterp/operators/op-dm-m.cc,
libinterp/operators/op-dm-s.cc, libinterp/operators/op-dm-scm.cc,
libinterp/operators/op-dm-sm.cc, libinterp/operators/op-dm-template.cc,
libinterp/operators/op-dms-template.cc, libinterp/operators/op-fcdm-fcdm.cc,
libinterp/operators/op-fcdm-fcm.cc, libinterp/operators/op-fcdm-fcs.cc,
libinterp/operators/op-fcdm-fdm.cc, libinterp/operators/op-fcdm-fm.cc,
libinterp/operators/op-fcdm-fs.cc, libinterp/operators/op-fcm-fcdm.cc,
libinterp/operators/op-fcm-fcm.cc, libinterp/operators/op-fcm-fcs.cc,
libinterp/operators/op-fcm-fdm.cc, libinterp/operators/op-fcm-fm.cc,
libinterp/operators/op-fcm-fs.cc, libinterp/operators/op-fcm-pm.cc,
libinterp/operators/op-fcn.cc, libinterp/operators/op-fcs-fcm.cc,
libinterp/operators/op-fcs-fcs.cc, libinterp/operators/op-fcs-fm.cc,
libinterp/operators/op-fcs-fs.cc, libinterp/operators/op-fdm-fcdm.cc,
libinterp/operators/op-fdm-fcm.cc, libinterp/operators/op-fdm-fcs.cc,
libinterp/operators/op-fdm-fdm.cc, libinterp/operators/op-fdm-fm.cc,
libinterp/operators/op-fdm-fs.cc, libinterp/operators/op-fm-fcdm.cc,
libinterp/operators/op-fm-fcm.cc, libinterp/operators/op-fm-fcs.cc,
libinterp/operators/op-fm-fdm.cc, libinterp/operators/op-fm-fm.cc,
libinterp/operators/op-fm-fs.cc, libinterp/operators/op-fm-pm.cc,
libinterp/operators/op-fs-fcm.cc, libinterp/operators/op-fs-fcs.cc,
libinterp/operators/op-fs-fm.cc, libinterp/operators/op-fs-fs.cc,
libinterp/operators/op-i16-i16.cc, libinterp/operators/op-i32-i32.cc,
libinterp/operators/op-i64-i64.cc, libinterp/operators/op-i8-i8.cc,
libinterp/operators/op-int-concat.cc, libinterp/operators/op-int.h,
libinterp/operators/op-m-cdm.cc, libinterp/operators/op-m-cm.cc,
libinterp/operators/op-m-cs.cc, libinterp/operators/op-m-dm.cc,
libinterp/operators/op-m-m.cc, libinterp/operators/op-m-pm.cc,
libinterp/operators/op-m-s.cc, libinterp/operators/op-m-scm.cc,
libinterp/operators/op-m-sm.cc, libinterp/operators/op-pm-cm.cc,
libinterp/operators/op-pm-fcm.cc, libinterp/operators/op-pm-fm.cc,
libinterp/operators/op-pm-m.cc, libinterp/operators/op-pm-pm.cc,
libinterp/operators/op-pm-scm.cc, libinterp/operators/op-pm-sm.cc,
libinterp/operators/op-pm-template.cc, libinterp/operators/op-range.cc,
libinterp/operators/op-s-cm.cc, libinterp/operators/op-s-cs.cc,
libinterp/operators/op-s-m.cc, libinterp/operators/op-s-s.cc,
libinterp/operators/op-s-scm.cc, libinterp/operators/op-s-sm.cc,
libinterp/operators/op-sbm-b.cc, libinterp/operators/op-sbm-bm.cc,
libinterp/operators/op-sbm-sbm.cc, libinterp/operators/op-scm-cm.cc,
libinterp/operators/op-scm-cs.cc, libinterp/operators/op-scm-m.cc,
libinterp/operators/op-scm-s.cc, libinterp/operators/op-scm-scm.cc,
libinterp/operators/op-scm-sm.cc, libinterp/operators/op-sm-cm.cc,
libinterp/operators/op-sm-cs.cc, libinterp/operators/op-sm-m.cc,
libinterp/operators/op-sm-s.cc, libinterp/operators/op-sm-scm.cc,
libinterp/operators/op-sm-sm.cc, libinterp/operators/op-str-m.cc,
libinterp/operators/op-str-s.cc, libinterp/operators/op-str-str.cc,
libinterp/operators/op-struct.cc, libinterp/operators/op-ui16-ui16.cc,
libinterp/operators/op-ui32-ui32.cc, libinterp/operators/op-ui64-ui64.cc,
libinterp/operators/op-ui8-ui8.cc, libinterp/operators/ops.h,
libinterp/options-usage.h, libinterp/parse-tree/lex.h,
libinterp/parse-tree/lex.ll, libinterp/parse-tree/oct-parse.in.yy,
libinterp/parse-tree/octave.gperf, libinterp/parse-tree/parse.h,
libinterp/parse-tree/pt-all.h, libinterp/parse-tree/pt-arg-list.cc,
libinterp/parse-tree/pt-arg-list.h, libinterp/parse-tree/pt-array-list.cc,
libinterp/parse-tree/pt-array-list.h, libinterp/parse-tree/pt-assign.cc,
libinterp/parse-tree/pt-assign.h, libinterp/parse-tree/pt-binop.cc,
libinterp/parse-tree/pt-binop.h, libinterp/parse-tree/pt-bp.cc,
libinterp/parse-tree/pt-bp.h, libinterp/parse-tree/pt-cbinop.cc,
libinterp/parse-tree/pt-cbinop.h, libinterp/parse-tree/pt-cell.cc,
libinterp/parse-tree/pt-cell.h, libinterp/parse-tree/pt-check.cc,
libinterp/parse-tree/pt-check.h, libinterp/parse-tree/pt-classdef.cc,
libinterp/parse-tree/pt-classdef.h, libinterp/parse-tree/pt-cmd.cc,
libinterp/parse-tree/pt-cmd.h, libinterp/parse-tree/pt-colon.cc,
libinterp/parse-tree/pt-colon.h, libinterp/parse-tree/pt-const.cc,
libinterp/parse-tree/pt-const.h, libinterp/parse-tree/pt-decl.cc,
libinterp/parse-tree/pt-decl.h, libinterp/parse-tree/pt-eval.cc,
libinterp/parse-tree/pt-eval.h, libinterp/parse-tree/pt-except.cc,
libinterp/parse-tree/pt-except.h, libinterp/parse-tree/pt-exp.cc,
libinterp/parse-tree/pt-exp.h, libinterp/parse-tree/pt-fcn-handle.cc,
libinterp/parse-tree/pt-fcn-handle.h, libinterp/parse-tree/pt-funcall.cc,
libinterp/parse-tree/pt-funcall.h, libinterp/parse-tree/pt-id.cc,
libinterp/parse-tree/pt-id.h, libinterp/parse-tree/pt-idx.cc,
libinterp/parse-tree/pt-idx.h, libinterp/parse-tree/pt-jump.cc,
libinterp/parse-tree/pt-jump.h, libinterp/parse-tree/pt-loop.cc,
libinterp/parse-tree/pt-loop.h, libinterp/parse-tree/pt-mat.cc,
libinterp/parse-tree/pt-mat.h, libinterp/parse-tree/pt-misc.cc,
libinterp/parse-tree/pt-misc.h, libinterp/parse-tree/pt-pr-code.cc,
libinterp/parse-tree/pt-pr-code.h, libinterp/parse-tree/pt-select.cc,
libinterp/parse-tree/pt-select.h, libinterp/parse-tree/pt-stmt.cc,
libinterp/parse-tree/pt-stmt.h, libinterp/parse-tree/pt-unop.cc,
libinterp/parse-tree/pt-unop.h, libinterp/parse-tree/pt-walk.h,
libinterp/parse-tree/pt.cc, libinterp/parse-tree/pt.h,
libinterp/parse-tree/token.cc, libinterp/parse-tree/token.h,
libinterp/template-inst/Array-jit.cc, libinterp/template-inst/Array-tc.cc,
libinterp/version.cc, libinterp/version.in.h, liboctave/array/Array-C.cc,
liboctave/array/Array-b.cc, liboctave/array/Array-ch.cc,
liboctave/array/Array-d.cc, liboctave/array/Array-f.cc,
liboctave/array/Array-fC.cc, liboctave/array/Array-i.cc,
liboctave/array/Array-idx-vec.cc, liboctave/array/Array-s.cc,
liboctave/array/Array-str.cc, liboctave/array/Array-util.cc,
liboctave/array/Array-util.h, liboctave/array/Array-voidp.cc,
liboctave/array/Array.cc, liboctave/array/Array.h,
liboctave/array/CColVector.cc, liboctave/array/CColVector.h,
liboctave/array/CDiagMatrix.cc, liboctave/array/CDiagMatrix.h,
liboctave/array/CMatrix.cc, liboctave/array/CMatrix.h,
liboctave/array/CNDArray.cc, liboctave/array/CNDArray.h,
liboctave/array/CRowVector.cc, liboctave/array/CRowVector.h,
liboctave/array/CSparse.cc, liboctave/array/CSparse.h,
liboctave/array/DiagArray2.cc, liboctave/array/DiagArray2.h,
liboctave/array/MArray-C.cc, liboctave/array/MArray-d.cc,
liboctave/array/MArray-f.cc, liboctave/array/MArray-fC.cc,
liboctave/array/MArray-i.cc, liboctave/array/MArray-s.cc,
liboctave/array/MArray.cc, liboctave/array/MArray.h,
liboctave/array/MDiagArray2.cc, liboctave/array/MDiagArray2.h,
liboctave/array/MSparse-C.cc, liboctave/array/MSparse-d.cc,
liboctave/array/MSparse.cc, liboctave/array/MSparse.h,
liboctave/array/Matrix.h, liboctave/array/MatrixType.cc,
liboctave/array/MatrixType.h, liboctave/array/PermMatrix.cc,
liboctave/array/PermMatrix.h, liboctave/array/Range.cc,
liboctave/array/Range.h, liboctave/array/Sparse-C.cc,
liboctave/array/Sparse-b.cc, liboctave/array/Sparse-d.cc,
liboctave/array/Sparse.cc, liboctave/array/Sparse.h,
liboctave/array/boolMatrix.cc, liboctave/array/boolMatrix.h,
liboctave/array/boolNDArray.cc, liboctave/array/boolNDArray.h,
liboctave/array/boolSparse.cc, liboctave/array/boolSparse.h,
liboctave/array/chMatrix.cc, liboctave/array/chMatrix.h,
liboctave/array/chNDArray.cc, liboctave/array/chNDArray.h,
liboctave/array/dColVector.cc, liboctave/array/dColVector.h,
liboctave/array/dDiagMatrix.cc, liboctave/array/dDiagMatrix.h,
liboctave/array/dMatrix.cc, liboctave/array/dMatrix.h,
liboctave/array/dNDArray.cc, liboctave/array/dNDArray.h,
liboctave/array/dRowVector.cc, liboctave/array/dRowVector.h,
liboctave/array/dSparse.cc, liboctave/array/dSparse.h,
liboctave/array/dim-vector.cc, liboctave/array/dim-vector.h,
liboctave/array/fCColVector.cc, liboctave/array/fCColVector.h,
liboctave/array/fCDiagMatrix.cc, liboctave/array/fCDiagMatrix.h,
liboctave/array/fCMatrix.cc, liboctave/array/fCMatrix.h,
liboctave/array/fCNDArray.cc, liboctave/array/fCNDArray.h,
liboctave/array/fCRowVector.cc, liboctave/array/fCRowVector.h,
liboctave/array/fColVector.cc, liboctave/array/fColVector.h,
liboctave/array/fDiagMatrix.cc, liboctave/array/fDiagMatrix.h,
liboctave/array/fMatrix.cc, liboctave/array/fMatrix.h,
liboctave/array/fNDArray.cc, liboctave/array/fNDArray.h,
liboctave/array/fRowVector.cc, liboctave/array/fRowVector.h,
liboctave/array/idx-vector.cc, liboctave/array/idx-vector.h,
liboctave/array/int16NDArray.cc, liboctave/array/int16NDArray.h,
liboctave/array/int32NDArray.cc, liboctave/array/int32NDArray.h,
liboctave/array/int64NDArray.cc, liboctave/array/int64NDArray.h,
liboctave/array/int8NDArray.cc, liboctave/array/int8NDArray.h,
liboctave/array/intNDArray.cc, liboctave/array/intNDArray.h,
liboctave/array/uint16NDArray.cc, liboctave/array/uint16NDArray.h,
liboctave/array/uint32NDArray.cc, liboctave/array/uint32NDArray.h,
liboctave/array/uint64NDArray.cc, liboctave/array/uint64NDArray.h,
liboctave/array/uint8NDArray.cc, liboctave/array/uint8NDArray.h,
liboctave/cruft/misc/blaswrap.c, liboctave/cruft/misc/cquit.c,
liboctave/cruft/misc/f77-extern.cc, liboctave/cruft/misc/f77-fcn.c,
liboctave/cruft/misc/f77-fcn.h, liboctave/cruft/misc/lo-error.c,
liboctave/cruft/misc/lo-error.h, liboctave/cruft/misc/quit.cc,
liboctave/cruft/misc/quit.h, liboctave/liboctave-build-info.h,
liboctave/liboctave-build-info.in.cc, liboctave/numeric/CollocWt.cc,
liboctave/numeric/CollocWt.h, liboctave/numeric/DAE.h,
liboctave/numeric/DAEFunc.h, liboctave/numeric/DAERT.h,
liboctave/numeric/DAERTFunc.h, liboctave/numeric/DASPK-opts.in,
liboctave/numeric/DASPK.cc, liboctave/numeric/DASPK.h,
liboctave/numeric/DASRT-opts.in, liboctave/numeric/DASRT.cc,
liboctave/numeric/DASRT.h, liboctave/numeric/DASSL-opts.in,
liboctave/numeric/DASSL.cc, liboctave/numeric/DASSL.h, liboctave/numeric/DET.h,
liboctave/numeric/EIG.cc, liboctave/numeric/EIG.h,
liboctave/numeric/LSODE-opts.in, liboctave/numeric/LSODE.cc,
liboctave/numeric/LSODE.h, liboctave/numeric/ODE.h,
liboctave/numeric/ODEFunc.h, liboctave/numeric/ODES.cc,
liboctave/numeric/ODES.h, liboctave/numeric/ODESFunc.h,
liboctave/numeric/Quad-opts.in, liboctave/numeric/Quad.cc,
liboctave/numeric/Quad.h, liboctave/numeric/aepbalance.cc,
liboctave/numeric/aepbalance.h, liboctave/numeric/base-dae.h,
liboctave/numeric/base-de.h, liboctave/numeric/base-min.h,
liboctave/numeric/bsxfun-decl.h, liboctave/numeric/bsxfun-defs.cc,
liboctave/numeric/bsxfun.h, liboctave/numeric/chol.cc,
liboctave/numeric/chol.h, liboctave/numeric/eigs-base.cc,
liboctave/numeric/eigs-base.h, liboctave/numeric/fEIG.cc,
liboctave/numeric/fEIG.h, liboctave/numeric/gepbalance.cc,
liboctave/numeric/gepbalance.h, liboctave/numeric/gsvd.cc,
liboctave/numeric/gsvd.h, liboctave/numeric/hess.cc, liboctave/numeric/hess.h,
liboctave/numeric/lo-amos-proto.h, liboctave/numeric/lo-arpack-proto.h,
liboctave/numeric/lo-blas-proto.h, liboctave/numeric/lo-fftpack-proto.h,
liboctave/numeric/lo-lapack-proto.h, liboctave/numeric/lo-mappers.cc,
liboctave/numeric/lo-mappers.h, liboctave/numeric/lo-qrupdate-proto.h,
liboctave/numeric/lo-ranlib-proto.h, liboctave/numeric/lo-slatec-proto.h,
liboctave/numeric/lo-specfun.cc, liboctave/numeric/lo-specfun.h,
liboctave/numeric/lu.cc, liboctave/numeric/lu.h,
liboctave/numeric/oct-convn.cc, liboctave/numeric/oct-convn.h,
liboctave/numeric/oct-fftw.cc, liboctave/numeric/oct-fftw.h,
liboctave/numeric/oct-norm.cc, liboctave/numeric/oct-norm.h,
liboctave/numeric/oct-rand.cc, liboctave/numeric/oct-rand.h,
liboctave/numeric/oct-spparms.cc, liboctave/numeric/oct-spparms.h,
liboctave/numeric/qr.cc, liboctave/numeric/qr.h, liboctave/numeric/qrp.cc,
liboctave/numeric/qrp.h, liboctave/numeric/randgamma.cc,
liboctave/numeric/randgamma.h, liboctave/numeric/randmtzig.cc,
liboctave/numeric/randmtzig.h, liboctave/numeric/randpoisson.cc,
liboctave/numeric/randpoisson.h, liboctave/numeric/schur.cc,
liboctave/numeric/schur.h, liboctave/numeric/sparse-chol.cc,
liboctave/numeric/sparse-chol.h, liboctave/numeric/sparse-dmsolve.cc,
liboctave/numeric/sparse-dmsolve.h, liboctave/numeric/sparse-lu.cc,
liboctave/numeric/sparse-lu.h, liboctave/numeric/sparse-qr.cc,
liboctave/numeric/sparse-qr.h, liboctave/numeric/svd.cc,
liboctave/numeric/svd.h, liboctave/operators/Sparse-diag-op-defs.h,
liboctave/operators/Sparse-op-decls.h, liboctave/operators/Sparse-op-defs.h,
liboctave/operators/Sparse-perm-op-defs.h, liboctave/operators/mk-ops.awk,
liboctave/operators/mx-base.h, liboctave/operators/mx-defs.h,
liboctave/operators/mx-ext.h, liboctave/operators/mx-inlines.cc,
liboctave/operators/mx-op-decl.h, liboctave/operators/mx-op-defs.h,
liboctave/operators/mx-ops, liboctave/operators/smx-ops,
liboctave/operators/vx-ops, liboctave/system/child-list.cc,
liboctave/system/child-list.h, liboctave/system/dir-ops.cc,
liboctave/system/dir-ops.h, liboctave/system/file-ops.cc,
liboctave/system/file-ops.h, liboctave/system/file-stat.cc,
liboctave/system/file-stat.h, liboctave/system/lo-sysdep.cc,
liboctave/system/lo-sysdep.h, liboctave/system/mach-info.cc,
liboctave/system/mach-info.h, liboctave/system/oct-env.cc,
liboctave/system/oct-env.h, liboctave/system/oct-group.cc,
liboctave/system/oct-group.h, liboctave/system/oct-passwd.cc,
liboctave/system/oct-passwd.h, liboctave/system/oct-syscalls.cc,
liboctave/system/oct-syscalls.h, liboctave/system/oct-time.cc,
liboctave/system/oct-time.h, liboctave/system/oct-uname.cc,
liboctave/system/oct-uname.h, liboctave/util/action-container.h,
liboctave/util/base-list.h, liboctave/util/byte-swap.h,
liboctave/util/caseless-str.h, liboctave/util/cmd-edit.cc,
liboctave/util/cmd-edit.h, liboctave/util/cmd-hist.cc,
liboctave/util/cmd-hist.h, liboctave/util/data-conv.cc,
liboctave/util/data-conv.h, liboctave/util/f2c-main.c,
liboctave/util/functor.h, liboctave/util/glob-match.cc,
liboctave/util/glob-match.h, liboctave/util/kpse.cc, liboctave/util/kpse.h,
liboctave/util/lo-array-errwarn.cc, liboctave/util/lo-array-errwarn.h,
liboctave/util/lo-array-gripes.cc, liboctave/util/lo-array-gripes.h,
liboctave/util/lo-cutils.c, liboctave/util/lo-cutils.h,
liboctave/util/lo-hash.cc, liboctave/util/lo-hash.h, liboctave/util/lo-ieee.cc,
liboctave/util/lo-ieee.h, liboctave/util/lo-macros.h, liboctave/util/lo-math.h,
liboctave/util/lo-regexp.cc, liboctave/util/lo-regexp.h,
liboctave/util/lo-traits.h, liboctave/util/lo-utils.cc,
liboctave/util/lo-utils.h, liboctave/util/oct-alloc.h,
liboctave/util/oct-base64.cc, liboctave/util/oct-base64.h,
liboctave/util/oct-binmap.h, liboctave/util/oct-cmplx.h,
liboctave/util/oct-glob.cc, liboctave/util/oct-glob.h,
liboctave/util/oct-inttypes-fwd.h, liboctave/util/oct-inttypes.cc,
liboctave/util/oct-inttypes.h, liboctave/util/oct-locbuf.cc,
liboctave/util/oct-locbuf.h, liboctave/util/oct-mutex.cc,
liboctave/util/oct-mutex.h, liboctave/util/oct-refcount.h,
liboctave/util/oct-rl-edit.c, liboctave/util/oct-rl-edit.h,
liboctave/util/oct-rl-hist.c, liboctave/util/oct-rl-hist.h,
liboctave/util/oct-shlib.cc, liboctave/util/oct-shlib.h,
liboctave/util/oct-sort.cc, liboctave/util/oct-sort.h,
liboctave/util/oct-sparse.h, liboctave/util/oct-string.cc,
liboctave/util/oct-string.h, liboctave/util/pathsearch.cc,
liboctave/util/pathsearch.h, liboctave/util/singleton-cleanup.cc,
liboctave/util/sparse-sort.cc, liboctave/util/sparse-sort.h,
liboctave/util/sparse-util.cc, liboctave/util/sparse-util.h,
liboctave/util/str-vec.cc, liboctave/util/str-vec.h,
liboctave/util/sun-utils.h, liboctave/util/unwind-prot.cc,
liboctave/util/unwind-prot.h, liboctave/util/url-transfer.cc,
liboctave/util/url-transfer.h, liboctave/wrappers/areadlink-wrapper.c,
liboctave/wrappers/areadlink-wrapper.h,
liboctave/wrappers/async-system-wrapper.c,
liboctave/wrappers/async-system-wrapper.h,
liboctave/wrappers/base64-wrappers.c, liboctave/wrappers/base64-wrappers.h,
liboctave/wrappers/canonicalize-file-name-wrapper.c,
liboctave/wrappers/canonicalize-file-name-wrapper.h,
liboctave/wrappers/dirent-wrappers.c, liboctave/wrappers/dirent-wrappers.h,
liboctave/wrappers/fcntl-wrappers.c, liboctave/wrappers/fcntl-wrappers.h,
liboctave/wrappers/filepos-wrappers.c, liboctave/wrappers/filepos-wrappers.h,
liboctave/wrappers/fpucw-wrappers.c, liboctave/wrappers/fpucw-wrappers.h,
liboctave/wrappers/gen-tempname-wrapper.c,
liboctave/wrappers/gen-tempname-wrapper.h, liboctave/wrappers/getopt-wrapper.c,
liboctave/wrappers/getopt-wrapper.h, liboctave/wrappers/glob-wrappers.c,
liboctave/wrappers/glob-wrappers.h, liboctave/wrappers/hash-wrappers.c,
liboctave/wrappers/hash-wrappers.h, liboctave/wrappers/math-wrappers.c,
liboctave/wrappers/math-wrappers.h, liboctave/wrappers/mkostemp-wrapper.c,
liboctave/wrappers/mkostemp-wrapper.h, liboctave/wrappers/nanosleep-wrapper.c,
liboctave/wrappers/nanosleep-wrapper.h, liboctave/wrappers/nproc-wrapper.c,
liboctave/wrappers/nproc-wrapper.h, liboctave/wrappers/octave-popen2.c,
liboctave/wrappers/octave-popen2.h, liboctave/wrappers/putenv-wrapper.c,
liboctave/wrappers/putenv-wrapper.h,
liboctave/wrappers/set-program-name-wrapper.c,
liboctave/wrappers/set-program-name-wrapper.h,
liboctave/wrappers/signal-wrappers.c, liboctave/wrappers/signal-wrappers.h,
liboctave/wrappers/stat-wrappers.c, liboctave/wrappers/stat-wrappers.h,
liboctave/wrappers/strdup-wrapper.c, liboctave/wrappers/strdup-wrapper.h,
liboctave/wrappers/strftime-wrapper.c, liboctave/wrappers/strftime-wrapper.h,
liboctave/wrappers/strmode-wrapper.c, liboctave/wrappers/strmode-wrapper.h,
liboctave/wrappers/strptime-wrapper.c, liboctave/wrappers/strptime-wrapper.h,
liboctave/wrappers/time-wrappers.c, liboctave/wrappers/time-wrappers.h,
liboctave/wrappers/tmpfile-wrapper.c, liboctave/wrappers/tmpfile-wrapper.h,
liboctave/wrappers/uname-wrapper.c, liboctave/wrappers/uname-wrapper.h,
liboctave/wrappers/unistd-wrappers.c, liboctave/wrappers/unistd-wrappers.h,
liboctave/wrappers/unsetenv-wrapper.c, liboctave/wrappers/unsetenv-wrapper.h,
liboctave/wrappers/vasprintf-wrapper.c, liboctave/wrappers/vasprintf-wrapper.h,
liboctave/wrappers/wait-for-input.c, liboctave/wrappers/wait-for-input.h,
liboctave/wrappers/wait-wrappers.c, liboctave/wrappers/wait-wrappers.h,
m4/acinclude.m4, oct-conf-post.in.h, run-octave.in, scripts/@ftp/ascii.m,
scripts/@ftp/binary.m, scripts/@ftp/cd.m, scripts/@ftp/close.m,
scripts/@ftp/delete.m, scripts/@ftp/dir.m, scripts/@ftp/display.m,
scripts/@ftp/ftp.m, scripts/@ftp/loadobj.m, scripts/@ftp/mget.m,
scripts/@ftp/mkdir.m, scripts/@ftp/mput.m, scripts/@ftp/rename.m,
scripts/@ftp/rmdir.m, scripts/@ftp/saveobj.m,
scripts/audio/@audioplayer/__get_properties__.m,
scripts/audio/@audioplayer/audioplayer.m, scripts/audio/@audioplayer/display.m,
scripts/audio/@audioplayer/get.m, scripts/audio/@audioplayer/isplaying.m,
scripts/audio/@audioplayer/pause.m, scripts/audio/@audioplayer/play.m,
scripts/audio/@audioplayer/playblocking.m, scripts/audio/@audioplayer/resume.m,
scripts/audio/@audioplayer/set.m, scripts/audio/@audioplayer/stop.m,
scripts/audio/@audioplayer/subsasgn.m, scripts/audio/@audioplayer/subsref.m,
scripts/audio/@audiorecorder/__get_properties__.m,
scripts/audio/@audiorecorder/audiorecorder.m,
scripts/audio/@audiorecorder/display.m, scripts/audio/@audiorecorder/get.m,
scripts/audio/@audiorecorder/getaudiodata.m,
scripts/audio/@audiorecorder/getplayer.m,
scripts/audio/@audiorecorder/isrecording.m,
scripts/audio/@audiorecorder/pause.m, scripts/audio/@audiorecorder/play.m,
scripts/audio/@audiorecorder/record.m,
scripts/audio/@audiorecorder/recordblocking.m,
scripts/audio/@audiorecorder/resume.m, scripts/audio/@audiorecorder/set.m,
scripts/audio/@audiorecorder/stop.m, scripts/audio/@audiorecorder/subsasgn.m,
scripts/audio/@audiorecorder/subsref.m, scripts/audio/lin2mu.m,
scripts/audio/mu2lin.m, scripts/audio/record.m, scripts/audio/sound.m,
scripts/audio/soundsc.m, scripts/deprecated/bitmax.m,
scripts/deprecated/comma.m, scripts/deprecated/isstr.m,
scripts/deprecated/mahalanobis.m, scripts/deprecated/md5sum.m,
scripts/deprecated/octave_config_info.m, scripts/deprecated/onenormest.m,
scripts/deprecated/paren.m, scripts/deprecated/semicolon.m,
scripts/deprecated/sleep.m, scripts/deprecated/usleep.m,
scripts/deprecated/wavread.m, scripts/deprecated/wavwrite.m,
scripts/elfun/acosd.m, scripts/elfun/acot.m, scripts/elfun/acotd.m,
scripts/elfun/acoth.m, scripts/elfun/acsc.m, scripts/elfun/acscd.m,
scripts/elfun/acsch.m, scripts/elfun/asec.m, scripts/elfun/asecd.m,
scripts/elfun/asech.m, scripts/elfun/asind.m, scripts/elfun/atan2d.m,
scripts/elfun/atand.m, scripts/elfun/cosd.m, scripts/elfun/cot.m,
scripts/elfun/cotd.m, scripts/elfun/coth.m, scripts/elfun/csc.m,
scripts/elfun/cscd.m, scripts/elfun/csch.m, scripts/elfun/sec.m,
scripts/elfun/secd.m, scripts/elfun/sech.m, scripts/elfun/sind.m,
scripts/elfun/tand.m, scripts/general/accumarray.m, scripts/general/accumdim.m,
scripts/general/bincoeff.m, scripts/general/bitcmp.m, scripts/general/bitget.m,
scripts/general/bitset.m, scripts/general/blkdiag.m,
scripts/general/cart2pol.m, scripts/general/cart2sph.m,
scripts/general/cell2mat.m, scripts/general/celldisp.m, scripts/general/chop.m,
scripts/general/circshift.m, scripts/general/common_size.m,
scripts/general/cplxpair.m, scripts/general/cumtrapz.m, scripts/general/curl.m,
scripts/general/dblquad.m, scripts/general/deal.m, scripts/general/deg2rad.m,
scripts/general/del2.m, scripts/general/display.m,
scripts/general/divergence.m, scripts/general/fieldnames.m,
scripts/general/flip.m, scripts/general/flipdim.m, scripts/general/fliplr.m,
scripts/general/flipud.m, scripts/general/grabcode.m,
scripts/general/gradient.m, scripts/general/idivide.m,
scripts/general/inputParser.m, scripts/general/int2str.m,
scripts/general/interp1.m, scripts/general/interp2.m,
scripts/general/interp3.m, scripts/general/interpft.m,
scripts/general/interpn.m, scripts/general/isdir.m, scripts/general/isequal.m,
scripts/general/isequaln.m, scripts/general/loadobj.m,
scripts/general/logspace.m, scripts/general/methods.m,
scripts/general/nargchk.m, scripts/general/narginchk.m,
scripts/general/nargoutchk.m, scripts/general/nextpow2.m,
scripts/general/nthargout.m, scripts/general/num2str.m,
scripts/general/pol2cart.m, scripts/general/polyarea.m,
scripts/general/postpad.m, scripts/general/prepad.m,
scripts/general/private/__isequal__.m, scripts/general/private/__splinen__.m,
scripts/general/publish.m, scripts/general/quadgk.m, scripts/general/quadl.m,
scripts/general/quadv.m, scripts/general/rad2deg.m, scripts/general/randi.m,
scripts/general/rat.m, scripts/general/repmat.m, scripts/general/rot90.m,
scripts/general/rotdim.m, scripts/general/saveobj.m, scripts/general/shift.m,
scripts/general/shiftdim.m, scripts/general/sortrows.m,
scripts/general/sph2cart.m, scripts/general/structfun.m,
scripts/general/subsindex.m, scripts/general/trapz.m,
scripts/general/triplequad.m, scripts/general/validateattributes.m,
scripts/geometry/convhull.m, scripts/geometry/delaunay.m,
scripts/geometry/delaunayn.m, scripts/geometry/dsearch.m,
scripts/geometry/dsearchn.m, scripts/geometry/griddata.m,
scripts/geometry/griddata3.m, scripts/geometry/griddatan.m,
scripts/geometry/inpolygon.m, scripts/geometry/rectint.m,
scripts/geometry/tsearchn.m, scripts/geometry/voronoi.m,
scripts/geometry/voronoin.m, scripts/gui/dialog.m, scripts/gui/errordlg.m,
scripts/gui/guidata.m, scripts/gui/guihandles.m, scripts/gui/helpdlg.m,
scripts/gui/inputdlg.m, scripts/gui/listdlg.m, scripts/gui/msgbox.m,
scripts/gui/private/__file_filter__.m,
scripts/gui/private/__fltk_file_filter__.m,
scripts/gui/private/__get_funcname__.m, scripts/gui/private/__is_function__.m,
scripts/gui/private/__uigetdir_fltk__.m,
scripts/gui/private/__uigetfile_fltk__.m,
scripts/gui/private/__uiobject_split_args__.m,
scripts/gui/private/__uiputfile_fltk__.m, scripts/gui/questdlg.m,
scripts/gui/uibuttongroup.m, scripts/gui/uicontextmenu.m,
scripts/gui/uicontrol.m, scripts/gui/uigetdir.m, scripts/gui/uigetfile.m,
scripts/gui/uimenu.m, scripts/gui/uipanel.m, scripts/gui/uipushtool.m,
scripts/gui/uiputfile.m, scripts/gui/uiresume.m, scripts/gui/uitoggletool.m,
scripts/gui/uitoolbar.m, scripts/gui/uiwait.m, scripts/gui/waitbar.m,
scripts/gui/waitforbuttonpress.m, scripts/gui/warndlg.m,
scripts/help/__gripe_missing_component__.m, scripts/help/__makeinfo__.m,
scripts/help/__unimplemented__.m, scripts/help/ans.m, scripts/help/doc.m,
scripts/help/doc_cache_create.m, scripts/help/error_ids.m,
scripts/help/get_first_help_sentence.m, scripts/help/help.m,
scripts/help/lookfor.m, scripts/help/print_usage.m,
scripts/help/private/__additional_help_message__.m,
scripts/help/private/__strip_html_tags__.m, scripts/help/type.m,
scripts/help/warning_ids.m, scripts/help/which.m, scripts/image/autumn.m,
scripts/image/bone.m, scripts/image/brighten.m, scripts/image/cmpermute.m,
scripts/image/cmunique.m, scripts/image/colorcube.m, scripts/image/colormap.m,
scripts/image/contrast.m, scripts/image/cool.m, scripts/image/copper.m,
scripts/image/cubehelix.m, scripts/image/flag.m, scripts/image/gray.m,
scripts/image/gray2ind.m, scripts/image/hot.m, scripts/image/hsv.m,
scripts/image/hsv2rgb.m, scripts/image/im2double.m, scripts/image/image.m,
scripts/image/imagesc.m, scripts/image/imfinfo.m, scripts/image/imformats.m,
scripts/image/imread.m, scripts/image/imshow.m, scripts/image/imwrite.m,
scripts/image/ind2gray.m, scripts/image/ind2rgb.m, scripts/image/iscolormap.m,
scripts/image/jet.m, scripts/image/lines.m, scripts/image/ntsc2rgb.m,
scripts/image/ocean.m, scripts/image/pink.m, scripts/image/prism.m,
scripts/image/private/__imfinfo__.m, scripts/image/private/__imread__.m,
scripts/image/private/__imwrite__.m,
scripts/image/private/colorspace_conversion_input_check.m,
scripts/image/private/colorspace_conversion_revert.m,
scripts/image/private/imageIO.m, scripts/image/private/imwrite_filename.m,
scripts/image/private/ind2x.m, scripts/image/rainbow.m,
scripts/image/rgb2hsv.m, scripts/image/rgb2ind.m, scripts/image/rgb2ntsc.m,
scripts/image/rgbplot.m, scripts/image/spinmap.m, scripts/image/spring.m,
scripts/image/summer.m, scripts/image/viridis.m, scripts/image/white.m,
scripts/image/winter.m, scripts/io/beep.m, scripts/io/csvread.m,
scripts/io/csvwrite.m, scripts/io/dlmwrite.m, scripts/io/fileread.m,
scripts/io/importdata.m, scripts/io/is_valid_file_id.m, scripts/io/strread.m,
scripts/io/textread.m, scripts/java/javaArray.m, scripts/java/java_get.m,
scripts/java/java_set.m, scripts/java/javaaddpath.m, scripts/java/javachk.m,
scripts/java/javaclasspath.m, scripts/java/javamem.m,
scripts/java/javarmpath.m, scripts/java/org/octave/ClassHelper.java,
scripts/java/org/octave/Matrix.java,
scripts/java/org/octave/OctClassLoader.java,
scripts/java/org/octave/Octave.java,
scripts/java/org/octave/OctaveReference.java, scripts/java/usejava.m,
scripts/linear-algebra/bandwidth.m,
scripts/linear-algebra/commutation_matrix.m, scripts/linear-algebra/cond.m,
scripts/linear-algebra/condeig.m, scripts/linear-algebra/condest.m,
scripts/linear-algebra/cross.m, scripts/linear-algebra/duplication_matrix.m,
scripts/linear-algebra/expm.m, scripts/linear-algebra/housh.m,
scripts/linear-algebra/isbanded.m, scripts/linear-algebra/isdefinite.m,
scripts/linear-algebra/isdiag.m, scripts/linear-algebra/ishermitian.m,
scripts/linear-algebra/issymmetric.m, scripts/linear-algebra/istril.m,
scripts/linear-algebra/istriu.m, scripts/linear-algebra/krylov.m,
scripts/linear-algebra/linsolve.m, scripts/linear-algebra/logm.m,
scripts/linear-algebra/normest.m, scripts/linear-algebra/normest1.m,
scripts/linear-algebra/null.m, scripts/linear-algebra/orth.m,
scripts/linear-algebra/planerot.m, scripts/linear-algebra/qzhess.m,
scripts/linear-algebra/rank.m, scripts/linear-algebra/rref.m,
scripts/linear-algebra/subspace.m, scripts/linear-algebra/trace.m,
scripts/linear-algebra/vech.m, scripts/miscellaneous/bug_report.m,
scripts/miscellaneous/bunzip2.m, scripts/miscellaneous/cast.m,
scripts/miscellaneous/citation.m, scripts/miscellaneous/compare_versions.m,
scripts/miscellaneous/computer.m, scripts/miscellaneous/copyfile.m,
scripts/miscellaneous/debug.m, scripts/miscellaneous/delete.m,
scripts/miscellaneous/desktop.m, scripts/miscellaneous/dir.m,
scripts/miscellaneous/dos.m, scripts/miscellaneous/edit.m,
scripts/miscellaneous/fact.m, scripts/miscellaneous/fileattrib.m,
scripts/miscellaneous/fileparts.m, scripts/miscellaneous/fullfile.m,
scripts/miscellaneous/genvarname.m, scripts/miscellaneous/getappdata.m,
scripts/miscellaneous/getfield.m, scripts/miscellaneous/gunzip.m,
scripts/miscellaneous/info.m, scripts/miscellaneous/inputname.m,
scripts/miscellaneous/isappdata.m, scripts/miscellaneous/isdeployed.m,
scripts/miscellaneous/ismac.m, scripts/miscellaneous/ispc.m,
scripts/miscellaneous/isunix.m, scripts/miscellaneous/license.m,
scripts/miscellaneous/list_primes.m, scripts/miscellaneous/ls.m,
scripts/miscellaneous/ls_command.m, scripts/miscellaneous/menu.m,
scripts/miscellaneous/mex.m, scripts/miscellaneous/mexext.m,
scripts/miscellaneous/mkdir.m, scripts/miscellaneous/mkoctfile.m,
scripts/miscellaneous/movefile.m, scripts/miscellaneous/namelengthmax.m,
scripts/miscellaneous/news.m, scripts/miscellaneous/open.m,
scripts/miscellaneous/orderfields.m, scripts/miscellaneous/pack.m,
scripts/miscellaneous/parseparams.m, scripts/miscellaneous/perl.m,
scripts/miscellaneous/private/__w2mpth__.m,
scripts/miscellaneous/private/display_info_file.m,
scripts/miscellaneous/python.m, scripts/miscellaneous/recycle.m,
scripts/miscellaneous/rmappdata.m, scripts/miscellaneous/run.m,
scripts/miscellaneous/setappdata.m, scripts/miscellaneous/setfield.m,
scripts/miscellaneous/substruct.m, scripts/miscellaneous/swapbytes.m,
scripts/miscellaneous/symvar.m, scripts/miscellaneous/tar.m,
scripts/miscellaneous/tempdir.m, scripts/miscellaneous/tmpnam.m,
scripts/miscellaneous/unix.m, scripts/miscellaneous/unpack.m,
scripts/miscellaneous/untar.m, scripts/miscellaneous/unzip.m,
scripts/miscellaneous/ver.m, scripts/miscellaneous/version.m,
scripts/miscellaneous/what.m, scripts/miscellaneous/xor.m,
scripts/miscellaneous/zip.m, scripts/mk-pkg-add, scripts/mkdoc.pl,
scripts/ode/ode23.m, scripts/ode/ode45.m, scripts/ode/odeget.m,
scripts/ode/odeplot.m, scripts/ode/odeset.m, scripts/ode/private/AbsRel_norm.m,
scripts/ode/private/integrate_adaptive.m, scripts/ode/private/kahan.m,
scripts/ode/private/ode_event_handler.m, scripts/ode/private/odedefaults.m,
scripts/ode/private/odemergeopts.m, scripts/ode/private/runge_kutta_23.m,
scripts/ode/private/runge_kutta_45_dorpri.m,
scripts/ode/private/runge_kutta_interpolate.m,
scripts/ode/private/starting_stepsize.m, scripts/optimization/__all_opts__.m,
scripts/optimization/fminbnd.m, scripts/optimization/fminsearch.m,
scripts/optimization/fminunc.m, scripts/optimization/fsolve.m,
scripts/optimization/fzero.m, scripts/optimization/glpk.m,
scripts/optimization/lsqnonneg.m, scripts/optimization/optimget.m,
scripts/optimization/optimset.m, scripts/optimization/pqpnonneg.m,
scripts/optimization/private/__fdjac__.m, scripts/optimization/qp.m,
scripts/optimization/sqp.m, scripts/path/matlabroot.m, scripts/path/pathdef.m,
scripts/path/private/getsavepath.m, scripts/path/savepath.m, scripts/pkg/pkg.m,
scripts/pkg/private/build.m, scripts/pkg/private/configure_make.m,
scripts/pkg/private/default_prefix.m, scripts/pkg/private/describe.m,
scripts/pkg/private/dirempty.m, scripts/pkg/private/get_description.m,
scripts/pkg/private/get_forge_download.m, scripts/pkg/private/get_forge_pkg.m,
scripts/pkg/private/get_unsatisfied_deps.m, scripts/pkg/private/getarch.m,
scripts/pkg/private/getarchdir.m, scripts/pkg/private/install.m,
scripts/pkg/private/installed_packages.m,
scripts/pkg/private/list_forge_packages.m, scripts/pkg/private/load_packages.m,
scripts/pkg/private/load_packages_and_dependencies.m,
scripts/pkg/private/rebuild.m, scripts/pkg/private/save_order.m,
scripts/pkg/private/uninstall.m, scripts/pkg/private/unload_packages.m,
scripts/plot/appearance/__clabel__.m,
scripts/plot/appearance/__getlegenddata__.m,
scripts/plot/appearance/annotation.m, scripts/plot/appearance/axis.m,
scripts/plot/appearance/box.m, scripts/plot/appearance/caxis.m,
scripts/plot/appearance/clabel.m, scripts/plot/appearance/daspect.m,
scripts/plot/appearance/datetick.m, scripts/plot/appearance/diffuse.m,
scripts/plot/appearance/grid.m, scripts/plot/appearance/gtext.m,
scripts/plot/appearance/hidden.m, scripts/plot/appearance/legend.m,
scripts/plot/appearance/lighting.m, scripts/plot/appearance/material.m,
scripts/plot/appearance/orient.m, scripts/plot/appearance/pbaspect.m,
scripts/plot/appearance/private/__axis_label__.m,
scripts/plot/appearance/private/__axis_limits__.m,
scripts/plot/appearance/shading.m, scripts/plot/appearance/specular.m,
scripts/plot/appearance/text.m, scripts/plot/appearance/title.m,
scripts/plot/appearance/view.m, scripts/plot/appearance/whitebg.m,
scripts/plot/appearance/xlabel.m, scripts/plot/appearance/xlim.m,
scripts/plot/appearance/ylabel.m, scripts/plot/appearance/ylim.m,
scripts/plot/appearance/zlabel.m, scripts/plot/appearance/zlim.m,
scripts/plot/draw/area.m, scripts/plot/draw/bar.m, scripts/plot/draw/barh.m,
scripts/plot/draw/camlight.m, scripts/plot/draw/colorbar.m,
scripts/plot/draw/comet.m, scripts/plot/draw/comet3.m,
scripts/plot/draw/compass.m, scripts/plot/draw/contour.m,
scripts/plot/draw/contour3.m, scripts/plot/draw/contourc.m,
scripts/plot/draw/contourf.m, scripts/plot/draw/cylinder.m,
scripts/plot/draw/ellipsoid.m, scripts/plot/draw/errorbar.m,
scripts/plot/draw/ezcontour.m, scripts/plot/draw/ezcontourf.m,
scripts/plot/draw/ezmesh.m, scripts/plot/draw/ezmeshc.m,
scripts/plot/draw/ezplot.m, scripts/plot/draw/ezplot3.m,
scripts/plot/draw/ezpolar.m, scripts/plot/draw/ezsurf.m,
scripts/plot/draw/ezsurfc.m, scripts/plot/draw/feather.m,
scripts/plot/draw/fill.m, scripts/plot/draw/fplot.m, scripts/plot/draw/hist.m,
scripts/plot/draw/isocaps.m, scripts/plot/draw/isocolors.m,
scripts/plot/draw/isonormals.m, scripts/plot/draw/isosurface.m,
scripts/plot/draw/light.m, scripts/plot/draw/line.m,
scripts/plot/draw/loglog.m, scripts/plot/draw/loglogerr.m,
scripts/plot/draw/mesh.m, scripts/plot/draw/meshc.m, scripts/plot/draw/meshz.m,
scripts/plot/draw/pareto.m, scripts/plot/draw/patch.m,
scripts/plot/draw/pcolor.m, scripts/plot/draw/peaks.m, scripts/plot/draw/pie.m,
scripts/plot/draw/pie3.m, scripts/plot/draw/plot.m, scripts/plot/draw/plot3.m,
scripts/plot/draw/plotmatrix.m, scripts/plot/draw/plotyy.m,
scripts/plot/draw/polar.m, scripts/plot/draw/private/__add_datasource__.m,
scripts/plot/draw/private/__bar__.m,
scripts/plot/draw/private/__calc_isovalue_from_data__.m,
scripts/plot/draw/private/__contour__.m,
scripts/plot/draw/private/__errplot__.m,
scripts/plot/draw/private/__ezplot__.m,
scripts/plot/draw/private/__interp_cube__.m,
scripts/plot/draw/private/__line__.m,
scripts/plot/draw/private/__marching_cube__.m,
scripts/plot/draw/private/__patch__.m, scripts/plot/draw/private/__pie__.m,
scripts/plot/draw/private/__plt__.m, scripts/plot/draw/private/__quiver__.m,
scripts/plot/draw/private/__rotate_around_axis__.m,
scripts/plot/draw/private/__scatter__.m, scripts/plot/draw/private/__stem__.m,
scripts/plot/draw/private/__unite_shared_vertices__.m,
scripts/plot/draw/quiver.m, scripts/plot/draw/quiver3.m,
scripts/plot/draw/rectangle.m, scripts/plot/draw/reducepatch.m,
scripts/plot/draw/reducevolume.m, scripts/plot/draw/ribbon.m,
scripts/plot/draw/rose.m, scripts/plot/draw/scatter.m,
scripts/plot/draw/scatter3.m, scripts/plot/draw/semilogx.m,
scripts/plot/draw/semilogxerr.m, scripts/plot/draw/semilogy.m,
scripts/plot/draw/semilogyerr.m, scripts/plot/draw/shrinkfaces.m,
scripts/plot/draw/slice.m, scripts/plot/draw/smooth3.m,
scripts/plot/draw/sombrero.m, scripts/plot/draw/sphere.m,
scripts/plot/draw/stairs.m, scripts/plot/draw/stem.m,
scripts/plot/draw/stem3.m, scripts/plot/draw/stemleaf.m,
scripts/plot/draw/surf.m, scripts/plot/draw/surface.m,
scripts/plot/draw/surfc.m, scripts/plot/draw/surfl.m,
scripts/plot/draw/surfnorm.m, scripts/plot/draw/tetramesh.m,
scripts/plot/draw/trimesh.m, scripts/plot/draw/triplot.m,
scripts/plot/draw/trisurf.m, scripts/plot/draw/waterfall.m,
scripts/plot/util/__actual_axis_position__.m,
scripts/plot/util/__default_plot_options__.m,
scripts/plot/util/__gnuplot_drawnow__.m,
scripts/plot/util/__next_line_color__.m,
scripts/plot/util/__next_line_style__.m, scripts/plot/util/__opengl_info__.m,
scripts/plot/util/__plt_get_axis_arg__.m, scripts/plot/util/__pltopt__.m,
scripts/plot/util/allchild.m, scripts/plot/util/ancestor.m,
scripts/plot/util/axes.m, scripts/plot/util/cla.m, scripts/plot/util/clf.m,
scripts/plot/util/close.m, scripts/plot/util/closereq.m,
scripts/plot/util/colstyle.m, scripts/plot/util/copyobj.m,
scripts/plot/util/figure.m, scripts/plot/util/findall.m,
scripts/plot/util/findfigs.m, scripts/plot/util/findobj.m,
scripts/plot/util/frame2im.m, scripts/plot/util/gca.m,
scripts/plot/util/gcbf.m, scripts/plot/util/gcbo.m, scripts/plot/util/gcf.m,
scripts/plot/util/gco.m, scripts/plot/util/ginput.m,
scripts/plot/util/gnuplot_binary.in.m, scripts/plot/util/graphics_toolkit.m,
scripts/plot/util/hdl2struct.m, scripts/plot/util/hggroup.m,
scripts/plot/util/hgload.m, scripts/plot/util/hgsave.m,
scripts/plot/util/hold.m, scripts/plot/util/im2frame.m,
scripts/plot/util/isaxes.m, scripts/plot/util/isfigure.m,
scripts/plot/util/ishghandle.m, scripts/plot/util/ishold.m,
scripts/plot/util/isprop.m, scripts/plot/util/linkaxes.m,
scripts/plot/util/linkprop.m, scripts/plot/util/meshgrid.m,
scripts/plot/util/ndgrid.m, scripts/plot/util/newplot.m,
scripts/plot/util/pan.m, scripts/plot/util/print.m, scripts/plot/util/printd.m,
scripts/plot/util/private/__add_default_menu__.m,
scripts/plot/util/private/__ghostscript__.m,
scripts/plot/util/private/__gnuplot_draw_axes__.m,
scripts/plot/util/private/__gnuplot_draw_figure__.m,
scripts/plot/util/private/__gnuplot_get_var__.m,
scripts/plot/util/private/__gnuplot_ginput__.m,
scripts/plot/util/private/__gnuplot_has_feature__.m,
scripts/plot/util/private/__gnuplot_has_terminal__.m,
scripts/plot/util/private/__gnuplot_open_stream__.m,
scripts/plot/util/private/__gnuplot_print__.m,
scripts/plot/util/private/__gnuplot_version__.m,
scripts/plot/util/private/__opengl_print__.m,
scripts/plot/util/private/__print_parse_opts__.m, scripts/plot/util/refresh.m,
scripts/plot/util/refreshdata.m, scripts/plot/util/rotate.m,
scripts/plot/util/rotate3d.m, scripts/plot/util/saveas.m,
scripts/plot/util/shg.m, scripts/plot/util/struct2hdl.m,
scripts/plot/util/subplot.m, scripts/plot/util/zoom.m,
scripts/polynomial/compan.m, scripts/polynomial/conv.m,
scripts/polynomial/deconv.m, scripts/polynomial/mkpp.m,
scripts/polynomial/mpoles.m, scripts/polynomial/padecoef.m,
scripts/polynomial/pchip.m, scripts/polynomial/poly.m,
scripts/polynomial/polyaffine.m, scripts/polynomial/polyder.m,
scripts/polynomial/polyeig.m, scripts/polynomial/polyfit.m,
scripts/polynomial/polygcd.m, scripts/polynomial/polyint.m,
scripts/polynomial/polyout.m, scripts/polynomial/polyreduce.m,
scripts/polynomial/polyval.m, scripts/polynomial/polyvalm.m,
scripts/polynomial/ppder.m, scripts/polynomial/ppint.m,
scripts/polynomial/ppjumps.m, scripts/polynomial/ppval.m,
scripts/polynomial/residue.m, scripts/polynomial/roots.m,
scripts/polynomial/spline.m, scripts/polynomial/splinefit.m,
scripts/polynomial/unmkpp.m, scripts/prefs/addpref.m, scripts/prefs/getpref.m,
scripts/prefs/ispref.m, scripts/prefs/prefdir.m, scripts/prefs/preferences.m,
scripts/prefs/private/loadprefs.m, scripts/prefs/private/prefsfile.m,
scripts/prefs/private/saveprefs.m, scripts/prefs/rmpref.m,
scripts/prefs/setpref.m, scripts/profiler/html/style.css,
scripts/profiler/profexplore.m, scripts/profiler/profexport.m,
scripts/profiler/profile.m, scripts/profiler/profshow.m,
scripts/set/intersect.m, scripts/set/ismember.m, scripts/set/powerset.m,
scripts/set/private/validsetargs.m, scripts/set/setdiff.m,
scripts/set/setxor.m, scripts/set/union.m, scripts/set/unique.m,
scripts/signal/arch_fit.m, scripts/signal/arch_rnd.m,
scripts/signal/arch_test.m, scripts/signal/arma_rnd.m,
scripts/signal/autoreg_matrix.m, scripts/signal/bartlett.m,
scripts/signal/blackman.m, scripts/signal/detrend.m, scripts/signal/diffpara.m,
scripts/signal/durbinlevinson.m, scripts/signal/fftconv.m,
scripts/signal/fftfilt.m, scripts/signal/fftshift.m, scripts/signal/filter2.m,
scripts/signal/fractdiff.m, scripts/signal/freqz.m,
scripts/signal/freqz_plot.m, scripts/signal/hamming.m,
scripts/signal/hanning.m, scripts/signal/hurst.m, scripts/signal/ifftshift.m,
scripts/signal/periodogram.m, scripts/signal/private/rectangle_lw.m,
scripts/signal/private/rectangle_sw.m, scripts/signal/private/triangle_lw.m,
scripts/signal/private/triangle_sw.m, scripts/signal/sinc.m,
scripts/signal/sinetone.m, scripts/signal/sinewave.m,
scripts/signal/spectral_adf.m, scripts/signal/spectral_xdf.m,
scripts/signal/spencer.m, scripts/signal/stft.m, scripts/signal/synthesis.m,
scripts/signal/unwrap.m, scripts/signal/yulewalker.m, scripts/sparse/bicg.m,
scripts/sparse/bicgstab.m, scripts/sparse/cgs.m, scripts/sparse/colperm.m,
scripts/sparse/eigs.m, scripts/sparse/etreeplot.m, scripts/sparse/gmres.m,
scripts/sparse/gplot.m, scripts/sparse/ichol.m, scripts/sparse/ilu.m,
scripts/sparse/nonzeros.m, scripts/sparse/pcg.m, scripts/sparse/pcr.m,
scripts/sparse/private/__sprand__.m, scripts/sparse/qmr.m,
scripts/sparse/spaugment.m, scripts/sparse/spconvert.m,
scripts/sparse/spdiags.m, scripts/sparse/speye.m, scripts/sparse/spfun.m,
scripts/sparse/spones.m, scripts/sparse/sprand.m, scripts/sparse/sprandn.m,
scripts/sparse/sprandsym.m, scripts/sparse/spstats.m, scripts/sparse/spy.m,
scripts/sparse/svds.m, scripts/sparse/treelayout.m, scripts/sparse/treeplot.m,
scripts/specfun/bessel.m, scripts/specfun/beta.m, scripts/specfun/betaln.m,
scripts/specfun/ellipke.m, scripts/specfun/expint.m, scripts/specfun/factor.m,
scripts/specfun/factorial.m, scripts/specfun/isprime.m, scripts/specfun/lcm.m,
scripts/specfun/legendre.m, scripts/specfun/nchoosek.m,
scripts/specfun/nthroot.m, scripts/specfun/perms.m, scripts/specfun/pow2.m,
scripts/specfun/primes.m, scripts/specfun/reallog.m, scripts/specfun/realpow.m,
scripts/specfun/realsqrt.m, scripts/special-matrix/gallery.m,
scripts/special-matrix/hadamard.m, scripts/special-matrix/hankel.m,
scripts/special-matrix/hilb.m, scripts/special-matrix/invhilb.m,
scripts/special-matrix/magic.m, scripts/special-matrix/pascal.m,
scripts/special-matrix/rosser.m, scripts/special-matrix/toeplitz.m,
scripts/special-matrix/vander.m, scripts/special-matrix/wilkinson.m,
scripts/startup/__finish__.m, scripts/statistics/base/center.m,
scripts/statistics/base/cloglog.m, scripts/statistics/base/corr.m,
scripts/statistics/base/cov.m, scripts/statistics/base/gls.m,
scripts/statistics/base/histc.m, scripts/statistics/base/iqr.m,
scripts/statistics/base/kendall.m, scripts/statistics/base/kurtosis.m,
scripts/statistics/base/logit.m, scripts/statistics/base/lscov.m,
scripts/statistics/base/mean.m, scripts/statistics/base/meansq.m,
scripts/statistics/base/median.m, scripts/statistics/base/mode.m,
scripts/statistics/base/moment.m, scripts/statistics/base/ols.m,
scripts/statistics/base/ppplot.m, scripts/statistics/base/prctile.m,
scripts/statistics/base/probit.m, scripts/statistics/base/qqplot.m,
scripts/statistics/base/quantile.m, scripts/statistics/base/range.m,
scripts/statistics/base/ranks.m, scripts/statistics/base/run_count.m,
scripts/statistics/base/runlength.m, scripts/statistics/base/skewness.m,
scripts/statistics/base/spearman.m, scripts/statistics/base/statistics.m,
scripts/statistics/base/std.m, scripts/statistics/base/table.m,
scripts/statistics/base/var.m, scripts/statistics/base/zscore.m,
scripts/statistics/distributions/betacdf.m,
scripts/statistics/distributions/betainv.m,
scripts/statistics/distributions/betapdf.m,
scripts/statistics/distributions/betarnd.m,
scripts/statistics/distributions/binocdf.m,
scripts/statistics/distributions/binoinv.m,
scripts/statistics/distributions/binopdf.m,
scripts/statistics/distributions/binornd.m,
scripts/statistics/distributions/cauchy_cdf.m,
scripts/statistics/distributions/cauchy_inv.m,
scripts/statistics/distributions/cauchy_pdf.m,
scripts/statistics/distributions/cauchy_rnd.m,
scripts/statistics/distributions/chi2cdf.m,
scripts/statistics/distributions/chi2inv.m,
scripts/statistics/distributions/chi2pdf.m,
scripts/statistics/distributions/chi2rnd.m,
scripts/statistics/distributions/discrete_cdf.m,
scripts/statistics/distributions/discrete_inv.m,
scripts/statistics/distributions/discrete_pdf.m,
scripts/statistics/distributions/discrete_rnd.m,
scripts/statistics/distributions/empirical_cdf.m,
scripts/statistics/distributions/empirical_inv.m,
scripts/statistics/distributions/empirical_pdf.m,
scripts/statistics/distributions/empirical_rnd.m,
scripts/statistics/distributions/expcdf.m,
scripts/statistics/distributions/expinv.m,
scripts/statistics/distributions/exppdf.m,
scripts/statistics/distributions/exprnd.m,
scripts/statistics/distributions/fcdf.m,
scripts/statistics/distributions/finv.m,
scripts/statistics/distributions/fpdf.m,
scripts/statistics/distributions/frnd.m,
scripts/statistics/distributions/gamcdf.m,
scripts/statistics/distributions/gaminv.m,
scripts/statistics/distributions/gampdf.m,
scripts/statistics/distributions/gamrnd.m,
scripts/statistics/distributions/geocdf.m,
scripts/statistics/distributions/geoinv.m,
scripts/statistics/distributions/geopdf.m,
scripts/statistics/distributions/geornd.m,
scripts/statistics/distributions/hygecdf.m,
scripts/statistics/distributions/hygeinv.m,
scripts/statistics/distributions/hygepdf.m,
scripts/statistics/distributions/hygernd.m,
scripts/statistics/distributions/kolmogorov_smirnov_cdf.m,
scripts/statistics/distributions/laplace_cdf.m,
scripts/statistics/distributions/laplace_inv.m,
scripts/statistics/distributions/laplace_pdf.m,
scripts/statistics/distributions/laplace_rnd.m,
scripts/statistics/distributions/logistic_cdf.m,
scripts/statistics/distributions/logistic_inv.m,
scripts/statistics/distributions/logistic_pdf.m,
scripts/statistics/distributions/logistic_rnd.m,
scripts/statistics/distributions/logncdf.m,
scripts/statistics/distributions/logninv.m,
scripts/statistics/distributions/lognpdf.m,
scripts/statistics/distributions/lognrnd.m,
scripts/statistics/distributions/nbincdf.m,
scripts/statistics/distributions/nbininv.m,
scripts/statistics/distributions/nbinpdf.m,
scripts/statistics/distributions/nbinrnd.m,
scripts/statistics/distributions/normcdf.m,
scripts/statistics/distributions/norminv.m,
scripts/statistics/distributions/normpdf.m,
scripts/statistics/distributions/normrnd.m,
scripts/statistics/distributions/poisscdf.m,
scripts/statistics/distributions/poissinv.m,
scripts/statistics/distributions/poisspdf.m,
scripts/statistics/distributions/poissrnd.m,
scripts/statistics/distributions/stdnormal_cdf.m,
scripts/statistics/distributions/stdnormal_inv.m,
scripts/statistics/distributions/stdnormal_pdf.m,
scripts/statistics/distributions/stdnormal_rnd.m,
scripts/statistics/distributions/tcdf.m,
scripts/statistics/distributions/tinv.m,
scripts/statistics/distributions/tpdf.m,
scripts/statistics/distributions/trnd.m,
scripts/statistics/distributions/unidcdf.m,
scripts/statistics/distributions/unidinv.m,
scripts/statistics/distributions/unidpdf.m,
scripts/statistics/distributions/unidrnd.m,
scripts/statistics/distributions/unifcdf.m,
scripts/statistics/distributions/unifinv.m,
scripts/statistics/distributions/unifpdf.m,
scripts/statistics/distributions/unifrnd.m,
scripts/statistics/distributions/wblcdf.m,
scripts/statistics/distributions/wblinv.m,
scripts/statistics/distributions/wblpdf.m,
scripts/statistics/distributions/wblrnd.m,
scripts/statistics/distributions/wienrnd.m,
scripts/statistics/models/logistic_regression.m,
scripts/statistics/models/private/logistic_regression_derivatives.m,
scripts/statistics/models/private/logistic_regression_likelihood.m,
scripts/statistics/tests/anova.m, scripts/statistics/tests/bartlett_test.m,
scripts/statistics/tests/chisquare_test_homogeneity.m,
scripts/statistics/tests/chisquare_test_independence.m,
scripts/statistics/tests/cor_test.m,
scripts/statistics/tests/f_test_regression.m,
scripts/statistics/tests/hotelling_test.m,
scripts/statistics/tests/hotelling_test_2.m,
scripts/statistics/tests/kolmogorov_smirnov_test.m,
scripts/statistics/tests/kolmogorov_smirnov_test_2.m,
scripts/statistics/tests/kruskal_wallis_test.m,
scripts/statistics/tests/manova.m, scripts/statistics/tests/mcnemar_test.m,
scripts/statistics/tests/prop_test_2.m, scripts/statistics/tests/run_test.m,
scripts/statistics/tests/sign_test.m, scripts/statistics/tests/t_test.m,
scripts/statistics/tests/t_test_2.m,
scripts/statistics/tests/t_test_regression.m,
scripts/statistics/tests/u_test.m, scripts/statistics/tests/var_test.m,
scripts/statistics/tests/welch_test.m,
scripts/statistics/tests/wilcoxon_test.m, scripts/statistics/tests/z_test.m,
scripts/statistics/tests/z_test_2.m, scripts/strings/base2dec.m,
scripts/strings/bin2dec.m, scripts/strings/blanks.m, scripts/strings/cstrcat.m,
scripts/strings/deblank.m, scripts/strings/dec2base.m,
scripts/strings/dec2bin.m, scripts/strings/dec2hex.m,
scripts/strings/findstr.m, scripts/strings/hex2dec.m, scripts/strings/index.m,
scripts/strings/isletter.m, scripts/strings/isstrprop.m,
scripts/strings/mat2str.m, scripts/strings/ostrsplit.m,
scripts/strings/regexptranslate.m, scripts/strings/rindex.m,
scripts/strings/str2num.m, scripts/strings/strcat.m, scripts/strings/strchr.m,
scripts/strings/strjoin.m, scripts/strings/strjust.m,
scripts/strings/strmatch.m, scripts/strings/strsplit.m,
scripts/strings/strtok.m, scripts/strings/strtrim.m,
scripts/strings/strtrunc.m, scripts/strings/substr.m,
scripts/strings/untabify.m, scripts/strings/validatestring.m,
scripts/testfun/__have_feature__.m, scripts/testfun/__printf_assert__.m,
scripts/testfun/__prog_output_assert__.m, scripts/testfun/__run_test_suite__.m,
scripts/testfun/assert.m, scripts/testfun/demo.m, scripts/testfun/example.m,
scripts/testfun/fail.m, scripts/testfun/private/compare_plot_demos.m,
scripts/testfun/private/dump_demos.m,
scripts/testfun/private/html_compare_plot_demos.m, scripts/testfun/rundemos.m,
scripts/testfun/runtests.m, scripts/testfun/speed.m, scripts/testfun/test.m,
scripts/time/addtodate.m, scripts/time/asctime.m, scripts/time/calendar.m,
scripts/time/clock.m, scripts/time/ctime.m, scripts/time/date.m,
scripts/time/datenum.m, scripts/time/datestr.m, scripts/time/datevec.m,
scripts/time/eomday.m, scripts/time/etime.m, scripts/time/is_leap_year.m,
scripts/time/now.m, scripts/time/weekday.m, src/display-available.c,
src/display-available.h, src/main-cli.cc, src/main-gui.cc, src/main.in.cc,
src/mkoctfile.in.cc, src/octave-build-info.h, src/octave-build-info.in.cc,
src/octave-config.in.cc, src/shared-fcns.h, test/args.tst,
test/classdef/classdef.tst, test/classes/classes.tst, test/colormaps.tst,
test/complex.tst, test/ctor-vs-method/ctor-vs-method.tst, test/diag-perm.tst,
test/error.tst, test/eval-catch.tst,
test/fcn-handle-derived-resolution/fcn-handle-derived-resolution.tst,
test/fntests.m, test/for.tst, test/func.tst, test/global.tst, test/if.tst,
test/index.tst, test/io.tst, test/jit.tst, test/line-continue.tst,
test/logical-index.tst, test/nest/nest.tst, test/null-assign.tst,
test/parser.tst, test/prefer.tst, test/range.tst, test/recursion.tst,
test/return.tst, test/slice.tst, test/struct.tst, test/switch.tst,
test/system.tst, test/transpose.tst, test/try.tst, test/unwind.tst,
test/while.tst:
Use the same Copyright formatting throughout Octave.
author | Rik <rik@octave.org> |
---|---|
date | Sun, 13 Nov 2016 20:33:47 -0800 |
parents | 7abc25e6206a |
children | 86b6f79d4de1 |
line wrap: on
line source
/* Copyright (C) 1996-2016 John W. Eaton Copyright (C) 2015-2016 Lachlan Andrew, Monash University 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 (HAVE_CONFIG_H) # include "config.h" #endif #include <cassert> #include <cctype> #include <cstring> #include <deque> #include <fstream> #include <iomanip> #include <iostream> #include <sstream> #include <string> #include "Array.h" #include "Cell.h" #include "byte-swap.h" #include "lo-ieee.h" #include "lo-mappers.h" #include "lo-utils.h" #include "oct-locbuf.h" #include "quit.h" #include "singleton-cleanup.h" #include "str-vec.h" #include "error.h" #include "errwarn.h" #include "input.h" #include "interpreter.h" #include "octave.h" #include "oct-stdstrm.h" #include "oct-stream.h" #include "ov.h" #include "ovl.h" #include "utils.h" // Programming Note: There are two very different error functions used // in the stream code. When invoked with "error (...)" the member // function from octave_stream or octave_base_stream is called. This // function sets the error state on the stream AND returns control to // the caller. The caller must then return a value at the end of the // function. When invoked with "::error (...)" the exception-based // error function from error.h is used. This function will throw an // exception and not return control to the caller. BE CAREFUL and // invoke the correct error function! // Possible values for conv_err: // // 1 : not a real scalar // 2 : value is NaN // 3 : value is not an integer static int convert_to_valid_int (const octave_value& tc, int& conv_err) { conv_err = 0; int retval = 0; double dval = 0.0; try { dval = tc.double_value (); } catch (const octave::execution_exception&) { recover_from_exception (); conv_err = 1; } if (! conv_err) { if (! lo_ieee_isnan (dval)) { int ival = octave::math::nint (dval); if (ival == dval) retval = ival; else conv_err = 3; } else conv_err = 2; } return retval; } static int get_size (double d, const std::string& who) { int retval = -1; if (lo_ieee_isnan (d)) ::error ("%s: NaN is invalid as size specification", who.c_str ()); if (octave::math::isinf (d)) retval = -1; else { if (d < 0.0) ::error ("%s: negative value invalid as size specification", who.c_str ()); retval = octave::math::nint (d); } return retval; } static void get_size (const Array<double>& size, octave_idx_type& nr, octave_idx_type& nc, bool& one_elt_size_spec, const std::string& who) { nr = -1; nc = -1; one_elt_size_spec = false; double dnr = -1.0; double dnc = -1.0; octave_idx_type sz_len = size.numel (); if (sz_len == 1) { one_elt_size_spec = true; dnr = size(0); dnc = (dnr == 0.0) ? 0.0 : 1.0; } else if (sz_len == 2) { dnr = size(0); if (octave::math::isinf (dnr)) ::error ("%s: invalid size specification", who.c_str ()); dnc = size(1); } else ::error ("%s: invalid size specification", who.c_str ()); nr = get_size (dnr, who); if (dnc >= 0.0) nc = get_size (dnc, who); } class scanf_format_elt { public: enum special_conversion { whitespace_conversion = 1, literal_conversion = 2, null = 3 }; scanf_format_elt (const char *txt = 0, int w = 0, bool d = false, char typ = '\0', char mod = '\0', const std::string& ch_class = "") : text (strsave (txt)), width (w), discard (d), type (typ), modifier (mod), char_class (ch_class) { } scanf_format_elt (const scanf_format_elt& e) : text (strsave (e.text)), width (e.width), discard (e.discard), type (e.type), modifier (e.modifier), char_class (e.char_class) { } scanf_format_elt& operator = (const scanf_format_elt& e) { if (this != &e) { text = strsave (e.text); width = e.width; discard = e.discard; type = e.type; modifier = e.modifier; char_class = e.char_class; } return *this; } ~scanf_format_elt (void) { delete [] text; } // The C-style format string. const char *text; // The maximum field width. int width; // 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 '['. char type; // A length modifier -- 'h', 'l', or 'L'. char modifier; // The class of characters in a '[' format. std::string char_class; }; class scanf_format_list { public: scanf_format_list (const std::string& fmt = ""); ~scanf_format_list (void); octave_idx_type num_conversions (void) { return nconv; } // The length can be different than the number of conversions. // For example, "x %d y %d z" has 2 conversions but the length of // the list is 3 because of the characters that appear after the // last conversion. size_t length (void) const { return fmt_elts.size (); } const scanf_format_elt *first (void) { curr_idx = 0; return current (); } const scanf_format_elt *current (void) const { return length () > 0 ? fmt_elts[curr_idx] : 0; } const scanf_format_elt *next (bool cycle = true) { static scanf_format_elt dummy (0, 0, false, scanf_format_elt::null, '\0', ""); curr_idx++; if (curr_idx >= length ()) { if (cycle) curr_idx = 0; else return &dummy; } return current (); } void printme (void) const; bool ok (void) const { return (nconv >= 0); } operator bool () const { return ok (); } bool all_character_conversions (void); bool all_numeric_conversions (void); private: // Number of conversions specified by this format string, or -1 if // invalid conversions have been found. octave_idx_type nconv; // Index to current element; size_t curr_idx; // List of format elements. std::deque<scanf_format_elt*> fmt_elts; // Temporary buffer. std::ostringstream buf; void add_elt_to_list (int width, bool discard, char type, char modifier, const std::string& char_class = ""); void process_conversion (const std::string& s, size_t& i, size_t n, int& width, bool& discard, char& type, char& modifier); int finish_conversion (const std::string& s, size_t& i, size_t n, int& width, bool discard, char& type, char modifier); // No copying! scanf_format_list (const scanf_format_list&); scanf_format_list& operator = (const scanf_format_list&); }; scanf_format_list::scanf_format_list (const std::string& s) : nconv (0), curr_idx (0), fmt_elts (), buf () { size_t n = s.length (); size_t i = 0; int width = 0; bool discard = false; char modifier = '\0'; char type = '\0'; bool have_more = true; while (i < n) { have_more = true; if (s[i] == '%') { // Process percent-escape conversion type. process_conversion (s, i, n, width, discard, type, modifier); have_more = (buf.tellp () != 0); } else if (isspace (s[i])) { type = scanf_format_elt::whitespace_conversion; width = 0; discard = false; modifier = '\0'; buf << " "; while (++i < n && isspace (s[i])) ; // skip whitespace add_elt_to_list (width, discard, type, modifier); have_more = false; } else { type = scanf_format_elt::literal_conversion; width = 0; discard = false; modifier = '\0'; while (i < n && ! isspace (s[i]) && s[i] != '%') buf << s[i++]; add_elt_to_list (width, discard, type, modifier); have_more = false; } if (nconv < 0) { have_more = false; break; } } if (have_more) add_elt_to_list (width, discard, type, modifier); buf.clear (); buf.str (""); } scanf_format_list::~scanf_format_list (void) { size_t n = fmt_elts.size (); for (size_t i = 0; i < n; i++) { scanf_format_elt *elt = fmt_elts[i]; delete elt; } } void scanf_format_list::add_elt_to_list (int width, bool discard, char type, char modifier, const std::string& char_class) { std::string text = buf.str (); if (! text.empty ()) { scanf_format_elt *elt = new scanf_format_elt (text.c_str (), width, discard, type, modifier, char_class); fmt_elts.push_back (elt); } buf.clear (); buf.str (""); } static std::string expand_char_class (const std::string& s) { std::string retval; size_t len = s.length (); size_t i = 0; while (i < len) { unsigned char c = s[i++]; if (c == '-' && i > 1 && i < len && ( static_cast<unsigned char> (s[i-2]) <= static_cast<unsigned char> (s[i]))) { // Add all characters from the range except the first (we // already added it below). for (c = s[i-2]+1; c < s[i]; c++) retval += c; } else { // Add the character to the class. Only add '-' if it is // the last character in the class. if (c != '-' || i == len) retval += c; } } return retval; } void scanf_format_list::process_conversion (const std::string& s, size_t& i, size_t n, int& width, bool& discard, char& type, char& modifier) { width = 0; discard = false; modifier = '\0'; type = '\0'; buf << s[i++]; bool have_width = false; while (i < n) { switch (s[i]) { case '*': if (discard) nconv = -1; else { discard = true; buf << s[i++]; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (have_width) nconv = -1; else { char c = s[i++]; width = 10 * width + c - '0'; have_width = true; buf << c; while (i < n && isdigit (s[i])) { c = s[i++]; width = 10 * width + c - '0'; buf << c; } } break; case 'h': case 'l': case 'L': if (modifier != '\0') nconv = -1; else modifier = s[i++]; break; case 'd': case 'i': case 'o': case 'u': case 'x': if (modifier == 'L') { nconv = -1; break; } goto fini; case 'e': case 'f': case 'g': if (modifier == 'h') { nconv = -1; break; } // No float or long double conversions, thanks. buf << 'l'; goto fini; case 'c': case 's': case 'p': case '%': case '[': if (modifier != '\0') { nconv = -1; break; } goto fini; fini: { if (finish_conversion (s, i, n, width, discard, type, modifier) == 0) return; } break; default: nconv = -1; break; } if (nconv < 0) break; } nconv = -1; } int scanf_format_list::finish_conversion (const std::string& s, size_t& i, size_t n, int& width, bool discard, char& type, char modifier) { int retval = 0; std::string char_class; size_t beg_idx = std::string::npos; size_t end_idx = std::string::npos; if (s[i] == '%') { type = '%'; buf << s[i++]; } else { type = s[i]; if (s[i] == '[') { buf << s[i++]; if (i < n) { beg_idx = i; if (s[i] == '^') { type = '^'; buf << s[i++]; if (i < n) { beg_idx = i; if (s[i] == ']') buf << s[i++]; } } else if (s[i] == ']') buf << s[i++]; } while (i < n && s[i] != ']') buf << s[i++]; if (i < n && s[i] == ']') { end_idx = i-1; buf << s[i++]; } if (s[i-1] != ']') retval = nconv = -1; } else buf << s[i++]; nconv++; } if (nconv >= 0) { if (beg_idx != std::string::npos && end_idx != std::string::npos) char_class = expand_char_class (s.substr (beg_idx, end_idx - beg_idx + 1)); add_elt_to_list (width, discard, type, modifier, char_class); } return retval; } void scanf_format_list::printme (void) const { size_t n = fmt_elts.size (); for (size_t i = 0; i < n; i++) { scanf_format_elt *elt = fmt_elts[i]; std::cerr << "width: " << elt->width << "\n" << "discard: " << elt->discard << "\n" << "type: "; if (elt->type == scanf_format_elt::literal_conversion) std::cerr << "literal text\n"; else if (elt->type == scanf_format_elt::whitespace_conversion) std::cerr << "whitespace\n"; else std::cerr << elt->type << "\n"; std::cerr << "modifier: " << elt->modifier << "\n" << "char_class: '" << undo_string_escapes (elt->char_class) << "'\n" << "text: '" << undo_string_escapes (elt->text) << "'\n\n"; } } bool scanf_format_list::all_character_conversions (void) { size_t n = fmt_elts.size (); if (n > 0) { for (size_t i = 0; i < n; i++) { scanf_format_elt *elt = fmt_elts[i]; switch (elt->type) { case 'c': case 's': case '%': case '[': case '^': case scanf_format_elt::literal_conversion: case scanf_format_elt::whitespace_conversion: break; default: return false; break; } } return true; } else return false; } bool scanf_format_list::all_numeric_conversions (void) { size_t n = fmt_elts.size (); if (n > 0) { for (size_t i = 0; i < n; i++) { scanf_format_elt *elt = fmt_elts[i]; switch (elt->type) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'e': case 'f': case 'g': break; default: return false; break; } } return true; } else return false; } class printf_format_elt { public: printf_format_elt (const char *txt = 0, int n = 0, int w = -1, int p = -1, const std::string& f = "", char typ = '\0', char mod = '\0') : text (strsave (txt)), args (n), fw (w), prec (p), flags (f), type (typ), modifier (mod) { } printf_format_elt (const printf_format_elt& e) : text (strsave (e.text)), args (e.args), fw (e.fw), prec (e.prec), flags (e.flags), type (e.type), modifier (e.modifier) { } printf_format_elt& operator = (const printf_format_elt& e) { if (this != &e) { text = strsave (e.text); args = e.args; fw = e.fw; prec = e.prec; flags = e.flags; type = e.type; modifier = e.modifier; } return *this; } ~printf_format_elt (void) { delete [] text; } // The C-style format string. const char *text; // How many args do we expect to consume? int args; // Field width. int fw; // Precision. int prec; // Flags -- '-', '+', ' ', '0', or '#'. std::string flags; // 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'. char modifier; }; class printf_format_list { public: printf_format_list (const std::string& fmt = ""); ~printf_format_list (void); octave_idx_type num_conversions (void) { return nconv; } const printf_format_elt *first (void) { curr_idx = 0; return current (); } const printf_format_elt *current (void) const { return length () > 0 ? fmt_elts[curr_idx] : 0; } size_t length (void) const { return fmt_elts.size (); } const printf_format_elt *next (bool cycle = true) { curr_idx++; if (curr_idx >= length ()) { if (cycle) curr_idx = 0; else return 0; } return current (); } bool last_elt_p (void) { return (curr_idx + 1 == length ()); } void printme (void) const; bool ok (void) const { return (nconv >= 0); } operator bool () const { return ok (); } private: // Number of conversions specified by this format string, or -1 if // invalid conversions have been found. octave_idx_type nconv; // Index to current element; size_t curr_idx; // List of format elements. std::deque<printf_format_elt*> fmt_elts; // Temporary buffer. std::ostringstream buf; void add_elt_to_list (int args, const std::string& flags, int fw, int prec, char type, char modifier); void process_conversion (const std::string& s, size_t& i, size_t n, int& args, std::string& flags, int& fw, int& prec, char& modifier, char& type); void finish_conversion (const std::string& s, size_t& i, int args, const std::string& flags, int fw, int prec, char modifier, char& type); // No copying! printf_format_list (const printf_format_list&); printf_format_list& operator = (const printf_format_list&); }; printf_format_list::printf_format_list (const std::string& s) : nconv (0), curr_idx (0), fmt_elts (), buf () { size_t n = s.length (); size_t i = 0; int args = 0; std::string flags; int fw = -1; int prec = -1; char modifier = '\0'; char type = '\0'; bool have_more = true; bool empty_buf = true; if (n == 0) { printf_format_elt *elt = new printf_format_elt ("", args, fw, prec, flags, type, modifier); fmt_elts.push_back (elt); } else { while (i < n) { have_more = true; empty_buf = (buf.tellp () == 0); switch (s[i]) { case '%': { if (empty_buf) { process_conversion (s, i, n, args, flags, fw, prec, type, modifier); // If there is nothing in the buffer, then // add_elt_to_list must have just been called, so we // are already done with the current element and we // don't need to call add_elt_to_list if this is our // last trip through the loop. have_more = (buf.tellp () != 0); } else add_elt_to_list (args, flags, fw, prec, type, modifier); } break; default: { args = 0; flags = ""; fw = -1; prec = -1; modifier = '\0'; type = '\0'; buf << s[i++]; empty_buf = false; } break; } if (nconv < 0) { have_more = false; break; } } if (have_more) add_elt_to_list (args, flags, fw, prec, type, modifier); buf.clear (); buf.str (""); } } printf_format_list::~printf_format_list (void) { size_t n = fmt_elts.size (); for (size_t i = 0; i < n; i++) { printf_format_elt *elt = fmt_elts[i]; delete elt; } } void printf_format_list::add_elt_to_list (int args, const std::string& flags, int fw, int prec, char type, char modifier) { std::string text = buf.str (); if (! text.empty ()) { printf_format_elt *elt = new printf_format_elt (text.c_str (), args, fw, prec, flags, type, modifier); fmt_elts.push_back (elt); } buf.clear (); buf.str (""); } void printf_format_list::process_conversion (const std::string& s, size_t& i, size_t n, int& args, std::string& flags, int& fw, int& prec, char& modifier, char& type) { args = 0; flags = ""; fw = -1; prec = -1; modifier = '\0'; type = '\0'; buf << s[i++]; bool nxt = false; while (i < n) { switch (s[i]) { case '-': case '+': case ' ': case '0': case '#': flags += s[i]; buf << s[i++]; break; default: nxt = true; break; } if (nxt) break; } if (i < n) { if (s[i] == '*') { fw = -2; args++; buf << s[i++]; } else { if (isdigit (s[i])) { int nn = 0; std::string tmp = s.substr (i); sscanf (tmp.c_str (), "%d%n", &fw, &nn); } while (i < n && isdigit (s[i])) buf << s[i++]; } } if (i < n && s[i] == '.') { // nothing before the . means 0. if (fw == -1) fw = 0; // . followed by nothing is 0. prec = 0; buf << s[i++]; if (i < n) { if (s[i] == '*') { prec = -2; args++; buf << s[i++]; } else { if (isdigit (s[i])) { int nn = 0; std::string tmp = s.substr (i); sscanf (tmp.c_str (), "%d%n", &prec, &nn); } while (i < n && isdigit (s[i])) buf << s[i++]; } } } if (i < n) { // Accept and record modifier, but don't place it in the format // item text. All integer conversions are handled as 64-bit // integers. switch (s[i]) { case 'h': case 'l': case 'L': modifier = s[i++]; break; default: break; } } if (i < n) finish_conversion (s, i, args, flags, fw, prec, modifier, type); else nconv = -1; } void printf_format_list::finish_conversion (const std::string& s, size_t& i, int args, const std::string& flags, int fw, int prec, char modifier, char& type) { switch (s[i]) { case 'd': case 'i': case 'o': case 'x': case 'X': case 'u': case 'c': if (modifier == 'L') { nconv = -1; break; } goto fini; case 'f': case 'e': case 'E': case 'g': case 'G': if (modifier == 'h' || modifier == 'l') { nconv = -1; break; } goto fini; case 's': case 'p': case '%': if (modifier != '\0') { nconv = -1; break; } goto fini; fini: type = s[i]; buf << s[i++]; if (type != '%' || args != 0) nconv++; if (type != '%') args++; add_elt_to_list (args, flags, fw, prec, type, modifier); break; default: nconv = -1; break; } } void printf_format_list::printme (void) const { size_t n = fmt_elts.size (); for (size_t i = 0; i < n; i++) { printf_format_elt *elt = fmt_elts[i]; std::cerr << "args: " << elt->args << "\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"; } } // Calculate x^n. Used for ...e+nn so that, for example, 1e2 is // exactly 100 and 5e-1 is 1/2 static double pown (double x, unsigned int n) { double retval = 1; for (unsigned int d = n; d; d >>= 1) { if (d & 1) retval *= x; x *= x; } return retval; } static Cell init_inf_nan (void) { Cell retval (dim_vector (1, 2)); retval(0) = Cell (octave_value ("inf")); retval(1) = Cell (octave_value ("nan")); return retval; } namespace octave { // Delimited stream, optimized to read strings of characters separated // by single-character delimiters. // // The reason behind this class is that octstream doesn't provide // seek/tell, but the opportunity has been taken to optimise for the // textscan workload. // // The function reads chunks into a 4kiB buffer, and marks where the // last delimiter occurs. Reads up to this delimiter can be fast. // After that last delimiter, the remaining text is moved to the front // of the buffer and the buffer is refilled. This also allows cheap // seek and tell operations within a "fast read" block. class delimited_stream { public: delimited_stream (std::istream& is, const std::string& delimiters, int longest_lookahead, octave_idx_type bsize = 4096); delimited_stream (std::istream& is, const delimited_stream& ds); ~delimited_stream (void); // Called when optimized sequence of get is finished. Ensures that // there is a remaining delimiter in buf, or loads more data in. void field_done (void) { if (idx >= last) refresh_buf (); } // Load new data into buffer, and set eob, last, idx. // Return EOF at end of file, 0 otherwise. int refresh_buf (void); // Get a character, relying on caller to call field_done if // a delimiter has been reached. int get (void) { if (delimited) return eof () ? std::istream::traits_type::eof () : *idx++; else return get_undelim (); } // Get a character, checking for underrun of the buffer. int get_undelim (void); // Read character that will be got by the next get. int peek (void) { return eof () ? std::istream::traits_type::eof () : *idx; } // Read character that will be got by the next get. int peek_undelim (void); // Undo a 'get' or 'get_undelim'. It is the caller's responsibility // to avoid overflow by calling putbacks only for a character got by // get() or get_undelim(), with no intervening // get, get_delim, field_done, refresh_buf, getline, read or seekg. void putback (char /*ch*/ = 0) { if (! eof ()) --idx; } int getline (std::string& dest, char delim); // int skipline (char delim); char *read (char *buffer, int size, char* &new_start); // Return a position suitable to "seekg", valid only within this // block between calls to field_done. char *tellg (void) { return idx; } void seekg (char *old_idx) { idx = old_idx; } bool eof (void) { return (eob == buf && i_stream.eof ()) || (flags & std::ios_base::eofbit); } operator const void* (void) { return (! eof () && ! flags) ? this : 0; } bool fail (void) { return flags & std::ios_base::failbit; } std::ios_base::iostate rdstate (void) { return flags; } void setstate (std::ios_base::iostate m) { flags = flags | m; } void clear (std::ios_base::iostate m = (std::ios_base::eofbit & ~std::ios_base::eofbit)) { flags = flags & m; } // Report if any characters have been consumed. // (get, read, etc. not cancelled by putback or seekg) void progress_benchmark (void) { progress_marker = idx; } bool no_progress (void) { return progress_marker == idx; } private: // Number of characters to read from the file at once. int bufsize; // Stream to read from. std::istream& i_stream; // Temporary storage for a "chunk" of data. char *buf; // Current read pointer. char *idx; // Location of last delimiter in the buffer at buf (undefined if // delimited is false). char *last; // Position after last character in buffer. char *eob; // True if there is delimiter in the bufer after idx. bool delimited; // Longest lookahead required. int longest; // Sequence of single-character delimiters. const std::string delims; // Position of start of buf in original stream. std::streampos buf_in_file; // Marker to see if a read consumes any characters. char *progress_marker; std::ios_base::iostate flags; // No copying! delimited_stream (const delimited_stream&); delimited_stream& operator = (const delimited_stream&); }; // Create a delimited stream, reading from is, with delimiters delims, // and allowing reading of up to tellg + longest_lookeahead. When is // is at EOF, lookahead may be padded by ASCII nuls. delimited_stream::delimited_stream (std::istream& is, const std::string& delimiters, int longest_lookahead, octave_idx_type bsize) : bufsize (bsize), i_stream (is), longest (longest_lookahead), delims (delimiters), flags (std::ios::failbit & ~std::ios::failbit) // can't cast 0 { buf = new char[bufsize]; eob = buf + bufsize; idx = eob; // refresh_buf shouldn't try to copy old data progress_marker = idx; refresh_buf (); // load the first batch of data } // Used to create a stream from a strstream from data read from a dstr. // FIXME: Find a more efficient approach. Perhaps derived dstr delimited_stream::delimited_stream (std::istream& is, const delimited_stream& ds) : bufsize (ds.bufsize), i_stream (is), longest (ds.longest), delims (ds.delims), flags (std::ios::failbit & ~std::ios::failbit) // can't cast 0 { buf = new char[bufsize]; eob = buf + bufsize; idx = eob; // refresh_buf shouldn't try to copy old data progress_marker = idx; refresh_buf (); // load the first batch of data } delimited_stream::~delimited_stream (void) { // Seek to the correct position in i_stream. if (! eof ()) { i_stream.clear (); i_stream.seekg (buf_in_file); i_stream.read (buf, idx - buf); } delete [] buf; } // Read a character from the buffer, refilling the buffer from the file // if necessary. int delimited_stream::get_undelim (void) { int retval; if (eof ()) { setstate (std::ios_base::failbit); return std::istream::traits_type::eof (); } if (idx < eob) retval = *idx++; else { refresh_buf (); if (eof ()) { setstate (std::ios_base::eofbit); retval = std::istream::traits_type::eof (); } else retval = *idx++; } if (idx >= last) delimited = false; return retval; } // Return the next character to be read without incrementing the // pointer, refilling the buffer from the file if necessary. int delimited_stream::peek_undelim (void) { int retval = get_undelim (); putback (); return retval; } // Copy remaining unprocessed data to the start of the buffer and load // new data to fill it. Return EOF if the file is at EOF before // reading any data and all of the data that has been read has been // processed. int delimited_stream::refresh_buf (void) { if (eof ()) return std::istream::traits_type::eof (); int retval; if (eob < idx) idx = eob; size_t old_remaining = eob - idx; octave_quit (); // allow ctrl-C if (old_remaining > 0) { buf_in_file += (idx - buf); memmove (buf, idx, old_remaining); } progress_marker -= idx - buf; // where original idx would have been idx = buf; int gcount; // chars read if (! i_stream.eof ()) { buf_in_file = i_stream.tellg (); // record for destructor i_stream.read (buf + old_remaining, bufsize - old_remaining); gcount = i_stream.gcount (); } else gcount = 0; eob = buf + old_remaining + gcount; last = eob; if (gcount == 0) { delimited = false; if (eob != buf) // no more data in file, but still some to go retval = 0; else // file and buffer are both done. retval = std::istream::traits_type::eof (); } else { delimited = true; for (last = eob - longest; last - buf >= 0; last--) { if (delims.find (*last) != std::string::npos) break; } if (last < buf) delimited = false; retval = 0; } // Ensure fast peek doesn't give valid char if (retval == std::istream::traits_type::eof ()) *idx = '\0'; // FIXME: check that no TreatAsEmpty etc starts w. \0? return retval; } // Return a pointer to a block of data of size size, assuming that a // sufficiently large buffer is available in buffer, if required. // If called when delimited == true, and size is no greater than // longest_lookahead then this will not call refresh_buf, so seekg // still works. Otherwise, seekg may be invalidated. char * delimited_stream::read (char *buffer, int size, char* &prior_tell) { char *retval; if (eob - idx > size) { retval = idx; idx += size; if (idx > last) delimited = false; } else { // If there was a tellg pointing to an earlier point than the current // read position, try to keep it in the active buffer. // In the current code, prior_tell==idx for each call, // so this is not necessary, just a precaution. if (eob - prior_tell + size < bufsize) { octave_idx_type gap = idx - prior_tell; idx = prior_tell; refresh_buf (); idx += gap; } else // can't keep the tellg in range. May skip some data. { refresh_buf (); } prior_tell = buf; if (eob - idx > size) { retval = idx; idx += size; if (idx > last) delimited = false; } else { if (size <= bufsize) // small read, but reached EOF { retval = idx; memset (eob, 0, size + (idx - buf)); idx += size; } else // Reading more than the whole buf; return it in buffer { retval = buffer; // FIXME: read bufsize at a time int i; for (i = 0; i < size && ! eof (); i++) *buffer++ = get_undelim (); if (eof ()) memset (buffer, 0, size - i); } } } return retval; } // Return in OUT an entire line, terminated by delim. On input, OUT // must have length at least 1. int delimited_stream::getline (std::string& out, char delim) { int len = out.length (), used = 0; int ch; while ((ch = get_undelim ()) != delim && ch != std::istream::traits_type::eof ()) { out[used++] = ch; if (used == len) { len <<= 1; out.resize (len); } } out.resize (used); field_done (); return ch; } // A single conversion specifier, such as %f or %c. class textscan_format_elt { public: enum special_conversion { whitespace_conversion = 1, literal_conversion = 2 }; textscan_format_elt (const std::string& txt, int w = 0, int p = -1, int bw = 0, bool dis = false, char typ = '\0', const std::string& ch_class = std::string ()) : text (txt), width (w), prec (p), bitwidth (bw), char_class (ch_class), type (typ), discard (dis), numeric (typ == 'd' || typ == 'u' || type == 'f' || type == 'n') { } textscan_format_elt (const textscan_format_elt& e) : text (e.text), width (e.width), prec (e.prec), bitwidth (e.bitwidth), char_class (e.char_class), type (e.type), discard (e.discard), numeric (e.numeric) { } textscan_format_elt& operator = (const textscan_format_elt& e) { if (this != &e) { text = e.text; width = e.width; prec = e.prec; bitwidth = e.bitwidth; discard = e.discard; type = e.type; numeric = e.numeric; char_class = e.char_class; } return *this; } // The C-style format string. std::string text; // The maximum field width. unsigned int width; // The maximum number of digits to read after the decimal in a // floating point conversion. int prec; // The size of the result. For integers, bitwidth may be 8, 16, 34, // or 64. For floating point values, bitwidth may be 32 or 64. int bitwidth; // The class of characters in a `[' or `^' format. std::string char_class; // Type of conversion // -- `d', `u', `f', `n', `s', `q', `c', `%', `C', `D', `[' or `^'. char type; // TRUE if we are not storing the result of this conversion. bool discard; // TRUE if the type is 'd', 'u', 'f', 'n' bool numeric; }; // The (parsed) sequence of format specifiers. class textscan; class textscan_format_list { public: textscan_format_list (const std::string& fmt = std::string (), const std::string& who = "textscan"); ~textscan_format_list (void); octave_idx_type num_conversions (void) const { return nconv; } // The length can be different than the number of conversions. // For example, "x %d y %d z" has 2 conversions but the length of // the list is 3 because of the characters that appear after the // last conversion. size_t numel (void) const { return fmt_elts.size (); } const textscan_format_elt *first (void) { curr_idx = 0; return current (); } const textscan_format_elt *current (void) const { return numel () > 0 ? fmt_elts[curr_idx] : 0; } const textscan_format_elt *next (bool cycle = true) { curr_idx++; if (curr_idx >= numel ()) { if (cycle) curr_idx = 0; else return 0; } return current (); } void printme (void) const; bool ok (void) const { return (nconv >= 0); } operator const void* (void) const { return ok () ? this : 0; } // What function name should be shown when reporting errors. std::string who; // True if number of %f to be set from data file. bool set_from_first; // At least one conversion specifier is s,q,c, or [...]. bool has_string; int read_first_row (delimited_stream& is, textscan& ts); std::list<octave_value> out_buf (void) const { return (output_container); } private: // Number of conversions specified by this format string, or -1 if // invalid conversions have been found. octave_idx_type nconv; // Index to current element; size_t curr_idx; // List of format elements. std::deque<textscan_format_elt*> fmt_elts; // list holding column arrays of types specified by conversions std::list<octave_value> output_container; // Temporary buffer. std::ostringstream buf; void add_elt_to_list (unsigned int width, int prec, int bitwidth, octave_value val_type, bool discard, char type, const std::string& char_class = std::string ()); void process_conversion (const std::string& s, size_t& i, size_t n); std::string parse_char_class (const std::string& pattern) const; int finish_conversion (const std::string& s, size_t& i, size_t n, unsigned int& width, int& prec, int& bitwidth, octave_value& val_type, bool discard, char& type); // No copying! textscan_format_list (const textscan_format_list&); textscan_format_list& operator = (const textscan_format_list&); }; // Main class to implement textscan. Read data and parse it // according to a format. // // The calling sequence is // // textscan scanner (); // scanner.scan (...); class OCTINTERP_API textscan { public: textscan (const std::string& who_arg = "textscan"); ~textscan (void) { } octave_value scan (std::istream& isp, const std::string& fmt, octave_idx_type ntimes, const octave_value_list& options, octave_idx_type& read_count); private: friend class textscan_format_list; // What function name should be shown when reporting errors. std::string who; std::string buf; // Three cases for delim_table and delim_list // 1. delim_table empty, delim_list empty: whitespace delimiters // 2. delim_table = look-up table of delim chars, delim_list empty. // 3. delim_table non-empty, delim_list = Cell array of delim strings std::string whitespace_table; // delim_table[i] == '\0' if i is not a delimiter. std::string delim_table; // String of delimiter characters. std::string delims; Cell comment_style; // How far ahead to look to detect an open comment. int comment_len; // First character of open comment. int comment_char; octave_idx_type buffer_size; std::string date_locale; // 'inf' and 'nan' for formatted_double. Cell inf_nan; // Array of strings of delimiters. Cell delim_list; // Longest delimiter. int delim_len; octave_value empty_value; std::string exp_chars; int header_lines; Cell treat_as_empty; // Longest string to treat as "N/A". int treat_as_empty_len; std::string whitespace; short eol1; short eol2; short return_on_error; bool collect_output; bool multiple_delims_as_one; bool default_exp; bool numeric_delim; octave_idx_type lines; octave_value do_scan (std::istream& isp, textscan_format_list& fmt_list, octave_idx_type ntimes); void parse_options (const octave_value_list& args, textscan_format_list& fmt_list); int read_format_once (delimited_stream& isp, textscan_format_list& fmt_list, std::list<octave_value>& retval, Array<octave_idx_type> row, int& done_after); void scan_one (delimited_stream& is, const textscan_format_elt& fmt, octave_value& ov, Array<octave_idx_type> row); // Methods to process a particular conversion specifier. double read_double (delimited_stream& is, const textscan_format_elt& fmt) const; void scan_complex (delimited_stream& is, const textscan_format_elt& fmt, Complex& val) const; int scan_bracket (delimited_stream& is, const std::string& pattern, std::string& val) const; int scan_caret (delimited_stream& is, const std::string& pattern, std::string& val) const; void scan_string (delimited_stream& is, const textscan_format_elt& fmt, std::string& val) const; void scan_cstring (delimited_stream& is, const textscan_format_elt& fmt, std::string& val) const; void scan_qstring (delimited_stream& is, const textscan_format_elt& fmt, std::string& val); // Helper methods. std::string read_until (delimited_stream& is, const Cell& delimiters, const std::string& ends) const; int lookahead (delimited_stream& is, const Cell& targets, int max_len, bool case_sensitive = true) const; bool match_literal (delimited_stream& isp, const textscan_format_elt& elem); int skip_whitespace (delimited_stream& is, bool EOLstop = false); int skip_delim (delimited_stream& is); bool is_delim (unsigned char ch) const { return ((delim_table.empty () && (isspace (ch) || ch == eol1 || ch == eol2)) || delim_table[ch] != '\0'); } bool isspace (unsigned int ch) const { return whitespace_table[ch & 0xff]; } // True if the only delimiter is whitespace. bool whitespace_delim (void) const { return delim_table.empty (); } // No copying! textscan (const textscan&); textscan& operator = (const textscan&); }; textscan_format_list::textscan_format_list (const std::string& s, const std::string& who_arg) : who (who_arg), set_from_first (false), has_string (false), nconv (0), curr_idx (0), fmt_elts (), buf () { size_t n = s.length (); size_t i = 0; unsigned int width = -1; // Unspecified width = max (except %c) int prec = -1; int bitwidth = 0; bool discard = false; char type = '\0'; bool have_more = true; if (s.empty ()) { buf.clear (); buf.str (""); buf << "%f"; bitwidth = 64; type = 'f'; add_elt_to_list (width, prec, bitwidth, octave_value (NDArray ()), discard, type); have_more = false; set_from_first = true; nconv = 1; } else { set_from_first = false; while (i < n) { have_more = true; if (s[i] == '%' && (i+1 == n || s[i+1] != '%')) { // Process percent-escape conversion type. process_conversion (s, i, n); // If there is nothing in the buffer, then add_elt_to_list // must have just been called, so we are already done with // the current element and we don't need to call // add_elt_to_list if this is our last trip through the // loop. have_more = (buf.tellp () != 0); } else if (isspace (s[i])) { while (++i < n && isspace (s[i])) /* skip whitespace */; have_more = false; } else { type = textscan_format_elt::literal_conversion; width = 0; prec = -1; bitwidth = 0; discard = true; while (i < n && ! isspace (s[i]) && (s[i] != '%' || (i+1 < n && s[i+1] == '%'))) { if (s[i] == '%') // if double %, skip one i++; buf << s[i++]; width++; } add_elt_to_list (width, prec, bitwidth, octave_value (), discard, type); have_more = false; } if (nconv < 0) { have_more = false; break; } } } if (have_more) add_elt_to_list (width, prec, bitwidth, octave_value (), discard, type); buf.clear (); buf.str (""); } textscan_format_list::~textscan_format_list (void) { size_t n = numel (); for (size_t i = 0; i < n; i++) { textscan_format_elt *elt = fmt_elts[i]; delete elt; } } void textscan_format_list::add_elt_to_list (unsigned int width, int prec, int bitwidth, octave_value val_type, bool discard, char type, const std::string& char_class) { std::string text = buf.str (); if (! text.empty ()) { textscan_format_elt *elt = new textscan_format_elt (text, width, prec, bitwidth, discard, type, char_class); if (! discard) output_container.push_back (val_type); fmt_elts.push_back (elt); } buf.clear (); buf.str (""); } void textscan_format_list::process_conversion (const std::string& s, size_t& i, size_t n) { unsigned width = 0; int prec = -1; int bitwidth = 0; bool discard = false; octave_value val_type; char type = '\0'; buf << s[i++]; bool have_width = false; while (i < n) { switch (s[i]) { case '*': if (discard) nconv = -1; else { discard = true; buf << s[i++]; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (have_width) nconv = -1; else { char c = s[i++]; width = width * 10 + c - '0'; have_width = true; buf << c; while (i < n && isdigit (s[i])) { c = s[i++]; width = width * 10 + c - '0'; buf << c; } if (i < n && s[i] == '.') { buf << s[i++]; prec = 0; while (i < n && isdigit (s[i])) { c = s[i++]; prec = prec * 10 + c - '0'; buf << c; } } } break; case 'd': case 'u': { bool done = true; buf << (type = s[i++]); if (i < n) { if (s[i] == '8') { bitwidth = 8; if (type == 'd') val_type = octave_value (int8NDArray ()); else val_type = octave_value (uint8NDArray ()); buf << s[i++]; } else if (s[i] == '1' && i+1 < n && s[i+1] == '6') { bitwidth = 16; if (type == 'd') val_type = octave_value (int16NDArray ()); else val_type = octave_value (uint16NDArray ()); buf << s[i++]; buf << s[i++]; } else if (s[i] == '3' && i+1 < n && s[i+1] == '2') { done = false; // use default size below buf << s[i++]; buf << s[i++]; } else if (s[i] == '6' && i+1 < n && s[i+1] == '4') { bitwidth = 64; if (type == 'd') val_type = octave_value (int64NDArray ()); else val_type = octave_value (uint64NDArray ()); buf << s[i++]; buf << s[i++]; } else done = false; } else done = false; if (! done) { bitwidth = 32; if (type == 'd') val_type = octave_value (int32NDArray ()); else val_type = octave_value (uint32NDArray ()); } goto fini; } case 'f': buf << (type = s[i++]); bitwidth = 64; if (i < n) { if (s[i] == '3' && i+1 < n && s[i+1] == '2') { bitwidth = 32; val_type = octave_value (FloatNDArray ()); buf << s[i++]; buf << s[i++]; } else if (s[i] == '6' && i+1 < n && s[i+1] == '4') { val_type = octave_value (NDArray ()); buf << s[i++]; buf << s[i++]; } else val_type = octave_value (NDArray ()); } else val_type = octave_value (NDArray ()); goto fini; case 'n': buf << (type = s[i++]); bitwidth = 64; val_type = octave_value (NDArray ()); goto fini; case 's': case 'q': case '[': case 'c': if (! discard) val_type = octave_value (Cell ()); buf << (type = s[i++]); has_string = true; goto fini; fini: { if (! have_width) { if (type == 'c') // %c defaults to one character width = 1; else width = static_cast<unsigned int> (-1); // others: unlimited } if (finish_conversion (s, i, n, width, prec, bitwidth, val_type, discard, type) == 0) return; } break; default: error ("%s: '%%%c' is not a valid format specifier", who.c_str (), s[i]); } if (nconv < 0) break; } nconv = -1; } // Parse [...] and [^...] // // Matlab does not expand expressions like A-Z, but they are useful, and // so we parse them "carefully". We treat '-' as a usual character // unless both start and end characters are from the same class (upper // case, lower case, numeric), or this is not the first '-' in the // pattern. // // Keep both a running list of characters and a mask of which chars have // occurred. The first is efficient for patterns with few characters. // The latter is efficient for [^...] patterns. std::string textscan_format_list::parse_char_class (const std::string& pattern) const { int len = pattern.length (); if (len == 0) return ""; std::string retval (256, '\0'); std::string mask (256, '\0'); // number of times chr has been seen int in = 0, out = 0; unsigned char ch, prev = 0; bool flip = false; ch = pattern[in]; if (ch == '^') { in++; flip = true; } mask[pattern[in]] = '\1'; retval[out++] = pattern[in++]; // even copy ']' if it is first bool prev_was_range = false; // disallow "a-m-z" as a pattern bool prev_prev_was_range = false; for (; in < len; in++) { bool was_range = false; ch = pattern[in]; if (ch == ']') break; if (prev == '-' && in > 1 && isalnum (ch) && ! prev_prev_was_range) { unsigned char start_of_range = pattern[in-2]; if (start_of_range < ch && ((isupper (ch) && isupper (start_of_range)) || (islower (ch) && islower (start_of_range)) || (isdigit (ch) && isdigit (start_of_range)) || mask['-'] > 1)) // not the first '-' { was_range = true; out--; mask['-']--; for (int i = start_of_range; i <= ch; i++) { if (mask[i] == '\0') { mask[i] = '\1'; retval[out++] = i; } } } } if (! was_range) { if (mask[ch]++ == 0) retval[out++] = ch; else if (ch != '-') warning_with_id ("octave:textscan-pattern", "%s: [...] contains two '%c's", who.c_str (), ch); if (prev == '-' && mask['-'] >= 2) warning_with_id ("octave:textscan-pattern", "%s: [...] contains two '-'s outside range expressions", who.c_str ()); } prev = ch; prev_prev_was_range = prev_was_range; prev_was_range = was_range; } if (flip) // [^...] { out = 0; for (int i = 0; i < 256; i++) if (! mask[i]) retval[out++] = i; } retval.resize (out); return retval; } int textscan_format_list::finish_conversion (const std::string& s, size_t& i, size_t n, unsigned int& width, int& prec, int& bitwidth, octave_value& val_type, bool discard, char& type) { int retval = 0; std::string char_class; size_t beg_idx = std::string::npos; size_t end_idx = std::string::npos; if (type != '%') { nconv++; if (type == '[') { if (i < n) { beg_idx = i; if (s[i] == '^') { type = '^'; buf << s[i++]; if (i < n) { beg_idx = i; if (s[i] == ']') buf << s[i++]; } } else if (s[i] == ']') buf << s[i++]; } while (i < n && s[i] != ']') buf << s[i++]; if (i < n && s[i] == ']') { end_idx = i-1; buf << s[i++]; } if (s[i-1] != ']') retval = nconv = -1; } } if (nconv >= 0) { if (beg_idx != std::string::npos && end_idx != std::string::npos) char_class = parse_char_class (s.substr (beg_idx, end_idx - beg_idx + 1)); add_elt_to_list (width, prec, bitwidth, val_type, discard, type, char_class); } return retval; } void textscan_format_list::printme (void) const { size_t n = numel (); for (size_t i = 0; i < n; i++) { textscan_format_elt *elt = fmt_elts[i]; std::cerr << "width: " << elt->width << "\n" << "digits " << elt->prec << "\n" << "bitwidth: " << elt->bitwidth << "\n" << "discard: " << elt->discard << "\n" << "type: "; if (elt->type == textscan_format_elt::literal_conversion) std::cerr << "literal text\n"; else if (elt->type == textscan_format_elt::whitespace_conversion) std::cerr << "whitespace\n"; else std::cerr << elt->type << "\n"; std::cerr << "char_class: `" << undo_string_escapes (elt->char_class) << "'\n" << "text: `" << undo_string_escapes (elt->text) << "'\n\n"; } } // If FORMAT is explicitly "", it is assumed to be "%f" repeated enough // times to read the first row of the file. Set it now. int textscan_format_list::read_first_row (delimited_stream& is, textscan& ts) { // Read first line and strip end-of-line, which may be two characters std::string first_line (20, ' '); is.getline (first_line, static_cast<char> (ts.eol2)); if (! first_line.empty () && first_line[first_line.length () - 1] == ts.eol1) first_line.resize (first_line.length () - 1); std::istringstream strstr (first_line); delimited_stream ds (strstr, is); dim_vector dv (1,1); // initial size of each output_container Complex val; octave_value val_type; nconv = 0; int max_empty = 1000; // failsafe, if ds fails but not with eof int retval = 0; // read line, creating output_container as we go while (! ds.eof ()) { bool already_skipped_delim = false; ts.skip_whitespace (ds); ds.progress_benchmark (); bool progress = false; ts.scan_complex (ds, *fmt_elts[0], val); if (ds.fail ()) { ds.clear (ds.rdstate () & ~std::ios::failbit); if (ds.eof ()) break; // Unless this was a missing value (i.e., followed by a delimiter), // return with an error status. ts.skip_delim (ds); if (ds.no_progress ()) { retval = 4; break; } already_skipped_delim = true; val = ts.empty_value.scalar_value (); if (! --max_empty) break; } if (val.imag () == 0) val_type = octave_value (NDArray (dv, val.real ())); else val_type = octave_value (ComplexNDArray (dv, val)); output_container.push_back (val_type); if (! already_skipped_delim) ts.skip_delim (ds); if (! progress && ds.no_progress ()) break; nconv++; } output_container.pop_front (); // discard empty element from constructor // Create fmt_list now that the size is known for (octave_idx_type i = 1; i < nconv; i++) fmt_elts.push_back (new textscan_format_elt (*fmt_elts[0])); return retval; // May have returned 4 above. } textscan::textscan (const std::string& who_arg) : who (who_arg), buf (), whitespace_table (), delim_table (), delims (), comment_style (), comment_len (0), comment_char (-2), buffer_size (0), date_locale (), inf_nan (init_inf_nan ()), empty_value (octave::numeric_limits<double>::NaN ()), exp_chars ("edED"), header_lines (0), treat_as_empty (), treat_as_empty_len (0), whitespace (" \b\t"), eol1 ('\r'), eol2 ('\n'), return_on_error (1), collect_output (false), multiple_delims_as_one (false), default_exp (true), numeric_delim (false), lines (0) { } octave_value textscan::scan (std::istream& isp, const std::string& fmt, octave_idx_type ntimes, const octave_value_list& options, octave_idx_type& count) { textscan_format_list fmt_list (fmt); parse_options (options, fmt_list); octave_value result = do_scan (isp, fmt_list, ntimes); // FIXME: this is probably not the best way to get count. The // position could easily be larger than octave_idx_type when using // 32-bit indexing. std::ios::iostate state = isp.rdstate (); isp.clear (); count = static_cast<octave_idx_type> (isp.tellg ()); isp.setstate (state); return result; } octave_value textscan::do_scan (std::istream& isp, textscan_format_list& fmt_list, octave_idx_type ntimes) { octave_value retval; if (fmt_list.num_conversions () == -1) error ("%s: invalid format specified", who.c_str ()); if (fmt_list.num_conversions () == 0) error ("%s: no valid format conversion specifiers", who.c_str ()); // skip the first header_lines std::string dummy; for (int i = 0; i < header_lines && isp; i++) getline (isp, dummy, static_cast<char> (eol2)); // Create our own buffered stream, for fast get/putback/tell/seek. // First, see how far ahead it should let us look. int max_lookahead = std::max (std::max (comment_len, treat_as_empty_len), std::max (delim_len, 3)); // 3 for NaN and Inf // Next, choose a buffer size to avoid reading too much, or too often. octave_idx_type buf_size = 4096; if (buffer_size) buf_size = buffer_size; else if (ntimes > 0) { // Avoid overflow of 80*ntimes... buf_size = std::min (buf_size, std::max (ntimes, 80 * ntimes)); buf_size = std::max (buf_size, ntimes); } // Finally, create the stream. delimited_stream is (isp, (delim_table.empty () ? whitespace + "\r\n" : delims), max_lookahead, buf_size); // Grow retval dynamically. "size" is half the initial size // (FIXME: Should we start smaller if ntimes is large?) octave_idx_type size = ((ntimes < 8 && ntimes >= 0) ? ntimes : 1); Array<octave_idx_type> row_idx (dim_vector (1,2)); row_idx(1) = 0; int err = 0; octave_idx_type row = 0; if (multiple_delims_as_one) // bug #44750? skip_delim (is); int done_after; // Number of columns read when EOF seen. // If FORMAT explicitly "", read first line and see how many "%f" match if (fmt_list.set_from_first) { err = fmt_list.read_first_row (is, *this); lines = 1; done_after = fmt_list.numel () + 1; if (! err) row = 1; // the above puts the first line into fmt_list.out_buf () } else done_after = fmt_list.out_buf ().size () + 1; std::list<octave_value> out = fmt_list.out_buf (); // We will later merge adjacent columns of the same type. // Check now which columns to merge. // Reals may become complex, and so we can't trust types // after reading in data. // If the format was "", that conversion may already have happened, // so force all to be merged (as all are %f). bool merge_with_prev[fmt_list.numel ()]; int conv = 0; if (collect_output) { int prev_type = -1; for (std::list<octave_value>::iterator col = out.begin (); col != out.end (); col++) { if (col->type_id () == prev_type || (fmt_list.set_from_first && prev_type != -1)) merge_with_prev [conv++] = true; else merge_with_prev [conv++] = false; prev_type = col->type_id (); } } // This should be caught by earlier code, but this avoids a possible // infinite loop below. if (fmt_list.num_conversions () == 0) error ("%s: No conversions specified", who.c_str ()); // Read the data. This is the main loop. if (! err) { for (/* row set ~30 lines above */; row < ntimes || ntimes == -1; row++) { if (row == 0 || row >= size) { size += size+1; for (std::list<octave_value>::iterator col = out.begin (); col != out.end (); col++) *col = (*col).resize (dim_vector (size, 1), 0); } row_idx(0) = row; err = read_format_once (is, fmt_list, out, row_idx, done_after); if ((err & ~1) > 0 || ! is || (lines >= ntimes && ntimes > -1)) break; } } if ((err & 4) && ! return_on_error) error ("%s: Read error in field %d of row %d", who.c_str (), done_after + 1, row + 1); // If file does not end in EOL, do not pad columns with NaN. bool uneven_columns = false; if (err & 4) uneven_columns = true; else if (isp.eof ()) { isp.clear (); isp.seekg (-1, std::ios_base::end); int last_char = isp.get (); isp.setstate (isp.eofbit); uneven_columns = (last_char != eol1 && last_char != eol2); } // convert return value to Cell array Array<octave_idx_type> ra_idx (dim_vector (1,2)); // (err & 1) means "error, and no columns read this row // FIXME: This may redundant now that done_after=0 says the same if (err & 1) done_after = out.size () + 1; int valid_rows = (row == ntimes) ? ntimes : (((err & 1) && (err & 8)) ? row : row+1); dim_vector dv (valid_rows, 1); ra_idx(0) = 0; int i = 0; if (! collect_output) { retval = Cell (dim_vector (1, out.size ())); for (std::list<octave_value>::iterator col = out.begin (); col != out.end (); col++, i++) { // trim last columns if that was requested if (i == done_after && uneven_columns) dv = dim_vector (std::max (valid_rows - 1, 0), 1); ra_idx(1) = i; retval = do_cat_op (retval, octave_value (Cell (col->resize (dv,0))), ra_idx); } } else // group adjacent cells of the same type into a single cell { octave_value cur; // current cell, accumulating columns octave_idx_type group_size = 0; // columns in this cell int prev_type = -1; conv = 0; retval = Cell (); for (std::list<octave_value>::iterator col = out.begin (); col != out.end (); col++) { if (! merge_with_prev [conv++]) // including first time { if (prev_type != -1) { ra_idx(1) = i++; retval = do_cat_op (retval, octave_value (Cell (cur)), ra_idx); } cur = octave_value (col->resize (dv,0)); group_size = 1; prev_type = col->type_id (); } else { ra_idx(1) = group_size++; cur = do_cat_op (cur, octave_value (col->resize (dv,0)), ra_idx); } } ra_idx(1) = i; retval = do_cat_op (retval, octave_value (Cell (cur)), ra_idx); } return retval; } // Read a double considering the "precision" field of FMT and the // EXP_CHARS option of OPTIONS. double textscan::read_double (delimited_stream& is, const textscan_format_elt& fmt) const { int sign = 1; unsigned int width_left = fmt.width; double retval = 0; bool valid = false; // syntactically correct double? int ch = is.peek (); if (ch == '+') { is.get (); ch = is.peek (); if (width_left) width_left--; } else if (ch == '-') { sign = -1; is.get (); ch = is.peek (); if (width_left) width_left--; } // Read integer part if (ch != '.') { if (ch >= '0' && ch <= '9') // valid if at least one digit valid = true; while (width_left-- && is && (ch = is.get ()) >= '0' && ch <= '9') retval = retval * 10 + (ch - '0'); width_left++; } // Read fractional part, up to specified precision if (ch == '.' && width_left) { double multiplier = 1; int precision = fmt.prec; int i; if (width_left) width_left--; // Consider width of '.' if (precision == -1) precision = 1<<30; // FIXME: Should be MAXINT if (! valid) // if there was nothing before '.'... is.get (); // ...ch was a "peek", not "get". for (i = 0; i < precision; i++) { if (width_left-- && is && (ch = is.get ()) >= '0' && ch <= '9') retval += (ch - '0') * (multiplier *= 0.1); else { width_left++; break; } } // round up if we truncated and the next digit is >= 5 if ((i == precision || ! width_left) && (ch = is.get ()) >= '5' && ch <= '9') retval += multiplier; if (i > 0) valid = true; // valid if at least one digit after '.' // skip remainder after '.', to field width, to look for exponent if (i == precision) while (width_left-- && is && (ch = is.get ()) >= '0' && ch <= '9') ; // discard width_left++; } // look for exponent part in, e.g., 6.023E+23 bool used_exp = false; if (valid && width_left > 1 && exp_chars.find (ch) != std::string::npos) { int ch1 = is.peek (); if (ch1 == '-' || ch1 == '+' || (ch1 >= '0' && ch1 <= '9')) { // if 1.0e+$ or some such, this will set failbit, as we want width_left--; // count "E" int exp = 0; int exp_sign = 1; if (ch1 == '+') { if (width_left) width_left--; is.get (); } else if (ch1 == '-') { exp_sign = -1; is.get (); if (width_left) width_left--; } valid = false; while (width_left-- && is && (ch = is.get ()) >= '0' && ch <= '9') { exp = exp*10 + ch - '0'; valid = true; } width_left++; if (ch != std::istream::traits_type::eof () && width_left) is.putback (ch); double multiplier = pown (10, exp); if (exp_sign > 0) retval *= multiplier; else retval /= multiplier; used_exp = true; } } is.clear (); if (! used_exp && ch != std::istream::traits_type::eof () && width_left) is.putback (ch); // Check for +/- inf and NaN if (! valid && width_left >= 3) { int i = lookahead (is, inf_nan, 3, false); // false -> case insensitive if (i == 0) { retval = octave::numeric_limits<double>::Inf (); valid = true; } else if (i == 1) { retval = octave::numeric_limits<double>::NaN (); valid = true; } } // Check for +/- inf and NaN if (! valid && width_left >= 3) { int i = lookahead (is, inf_nan, 3, false); // false -> case insensitive if (i == 0) { retval = octave::numeric_limits<double>::Inf (); valid = true; } else if (i == 1) { retval = octave::numeric_limits<double>::NaN (); valid = true; } } if (! valid) is.setstate (std::ios::failbit); else is.setstate (is.rdstate () & ~std::ios::failbit); return retval * sign; } // Read a single number: real, complex, inf, NaN, possibly with limited // precision. Calls to this should be preceded by skip_whitespace. // Calling that inside scan_complex would violate its const declaration. void textscan::scan_complex (delimited_stream& is, const textscan_format_elt& fmt, Complex& val) const { double im = 0; double re = 0; bool as_empty = false; // did we fail but match a "treat_as_empty" string? bool inf = false; int ch = is.peek (); if (ch == '+' || ch == '-') // check for [+-][ij] with no coefficients { ch = is.get (); int ch2 = is.peek (); if (ch2 == 'i' || ch2 == 'j') { double value = 1; is.get (); // Check not -inf if (is.peek () == 'n') { char *pos = is.tellg (); std::ios::iostate state = is.rdstate (); is.get (); ch2 = is.get (); if (ch2 == 'f') { inf = true; re = (ch == '+') ? octave::numeric_limits<double>::Inf () : -octave::numeric_limits<double>::Inf (); value = 0; } else { is.clear (state); is.seekg (pos); // reset to position before look-ahead } } im = (ch == '+') ? value : -value; } else is.putback (ch); } if (! im && ! inf) // if not [+-][ij] or [+-]inf, read real normally { char *pos = is.tellg (); std::ios::iostate state = is.rdstate (); //re = octave_read_value<double> (is); re = read_double (is, fmt); // check for "treat as empty" string if (treat_as_empty.numel () && (is.fail () || octave::math::is_NaN_or_NA (Complex (re)) || re == octave::numeric_limits<double>::Inf ())) { for (int i = 0; i < treat_as_empty.numel (); i++) { if (ch == treat_as_empty (i).string_value ()[0]) { as_empty = true; // first char matches, so read the lot break; } } if (as_empty) // if first char matched... { as_empty = false; // ...look for the whole string is.clear (state); // treat_as_empty "-" causes partial read is.seekg (pos); // reset to position before failed read // treat_as_empty strings may be different sizes. // Read ahead longest, put it all back, then re-read the string // that matches. std::string look_buf (treat_as_empty_len, '\0'); char *look = is.read (&look_buf[0], look_buf.size (), pos); is.clear (state); is.seekg (pos); // reset to position before look-ahead // FIXME: is.read could invalidate pos for (int i = 0; i < treat_as_empty.numel (); i++) { std::string s = treat_as_empty (i).string_value (); if (! strncmp (s.c_str (), look, s.size ())) { as_empty = true; // read just the right amount is.read (&look_buf[0], s.size (), pos); break; } } } } if (! is.eof () && ! as_empty) { state = is.rdstate (); // before tellg, since that fails at EOF pos = is.tellg (); ch = is.peek (); // ch == EOF if read failed; no need to chk fail if (ch == 'i' || ch == 'j') // pure imaginary { is.get (); im = re; re = 0; } else if (ch == '+' || ch == '-') // see if it is real+imag[ij] { // save stream state in case we have to restore it pos = is.tellg (); state = is.rdstate (); //im = octave_read_value<double> (is); im = read_double (is, fmt); if (is.fail ()) im = 1; if (is.peek () == 'i' || is.peek () == 'j') is.get (); else { im = 0; // no valid imaginary part. Restore state is.clear (state); // eof shouldn't cause fail. is.seekg (pos); } } else if (is.eof ()) // we've read enough to be a "valid" read is.clear (state); // failed peek shouldn't cause fail } } if (as_empty) val = empty_value.scalar_value (); else val = Complex (re, im); } // Return in VAL the run of characters from IS NOT contained in PATTERN. int textscan::scan_caret (delimited_stream& is, const std::string& pattern, std::string& val) const { int c1 = std::istream::traits_type::eof (); std::ostringstream obuf; // Is this optimized for growing? while (is && ((c1 = (is && ! is.eof ()) ? is.get_undelim () : std::istream::traits_type::eof ()) != std::istream::traits_type::eof ()) && pattern.find (c1) == std::string::npos) obuf << static_cast<char> (c1); val = obuf.str (); if (c1 != std::istream::traits_type::eof ()) is.putback (c1); return c1; } // Read until one of the strings in DELIMITERS is found. For // efficiency, ENDS is a list of the last character of each delimiter. std::string textscan::read_until (delimited_stream& is, const Cell& delimiters, const std::string& ends) const { std::string retval (""); bool done = false; do { // find sequence ending with an ending char std::string next; scan_caret (is, ends.c_str (), next); retval = retval + next; // FIXME: could use repeated doubling of size int last = (! is.eof () ? is.get_undelim () : std::istream::traits_type::eof ()); if (last != std::istream::traits_type::eof ()) { retval = retval + static_cast<char> (last); for (int i = 0; i < delimiters.numel (); i++) { std::string delim = delimiters(i).string_value (); size_t start = (retval.length () > delim.length () ? retval.length () - delim.length () : 0); std::string may_match = retval.substr (start); if (may_match == delim) { done = true; retval = retval.substr (0, start); break; } } } } while (! done && is && ! is.eof ()); return retval; } // Read stream until either fmt.width chars have been read, or // options.delimiter has been found. Does *not* rely on fmt being 's'. // Used by formats like %6f to limit to 6. void textscan::scan_string (delimited_stream& is, const textscan_format_elt& fmt, std::string& val) const { if (delim_list.is_empty ()) { unsigned int i = 0; unsigned int width = fmt.width; for (i = 0; i < width; i++) { if (i+1 > val.length ()) val = val + val + ' '; // grow even if empty int ch = is.get (); if (is_delim (ch) || ch == std::istream::traits_type::eof ()) { is.putback (ch); break; } else val[i] = ch; } val = val.substr (0, i); // trim pre-allocation } else // Cell array of multi-character delimiters { std::string ends (""); for (int i = 0; i < delim_list.numel (); i++) { std::string tmp = delim_list(i).string_value (); ends += tmp.substr (tmp.length () - 1); } val = textscan::read_until (is, delim_list, ends); } } // Return in VAL the run of characters from IS contained in PATTERN. int textscan::scan_bracket (delimited_stream& is, const std::string& pattern, std::string& val) const { int c1 = std::istream::traits_type::eof (); std::ostringstream obuf; // Is this optimized for growing? while (is && pattern.find (c1 = is.get_undelim ()) != std::string::npos) obuf << static_cast<char> (c1); val = obuf.str (); if (c1 != std::istream::traits_type::eof ()) is.putback (c1); return c1; } // Return in VAL a string, either delimited by whitespace/delimiters, or // enclosed in a pair of double quotes ("..."). Enclosing quotes are // removed. A consecutive pair "" is inserted into VAL as a single ". void textscan::scan_qstring (delimited_stream& is, const textscan_format_elt& fmt, std::string& val) { skip_whitespace (is); if (is.peek () != '\"') scan_string (is, fmt, val); else { is.get (); scan_caret (is, "\"", val); // read everything until " is.get (); // swallow " while (is && is.peek () == '\"') // if double ", insert one in stream, { // and keep looking for single " is.get (); std::string val1; scan_caret (is, "\"", val1); val = val + "\"" + val1; is.get_undelim (); } } } // Read from IS into VAL a string of the next fmt.width characters, // including any whitespace or delimiters. void textscan::scan_cstring (delimited_stream& is, const textscan_format_elt& fmt, std::string& val) const { val.resize (fmt.width); for (unsigned int i = 0; is && i < fmt.width; i++) { int ch = is.get_undelim (); if (ch != std::istream::traits_type::eof ()) val[i] = ch; else { val.resize (i); break; } } } // Read a single '%...' conversion and place it in position ROW of OV. void textscan::scan_one (delimited_stream& is, const textscan_format_elt& fmt, octave_value& ov, Array<octave_idx_type> row) { skip_whitespace (is); is.clear (); octave_value val; if (fmt.numeric) { if (fmt.type == 'f' || fmt.type == 'n') { Complex v; skip_whitespace (is); scan_complex (is, fmt, v); if (! fmt.discard && ! is.fail ()) { if (fmt.bitwidth == 64) { if (ov.is_real_type () && v.imag () == 0) ov.internal_rep ()->fast_elem_insert (row(0), v.real ()); else { if (ov.is_real_type ()) // cat does type conversion ov = do_cat_op (ov, octave_value (v), row); else ov.internal_rep ()->fast_elem_insert (row(0), v); } } else { if (ov.is_real_type () && v.imag () == 0) ov.internal_rep ()->fast_elem_insert (row(0), float (v.real ())); else { if (ov.is_real_type ()) // cat does type conversion ov = do_cat_op (ov, octave_value (v), row); else ov.internal_rep ()->fast_elem_insert (row(0), FloatComplex (v)); } } } } else { double v; // Matlab docs say 1e30 etc should be valid for %d and // 1000 as a %d8 should be 127, so read as double. // Some loss of precision for d64 and u64. skip_whitespace (is); v = read_double (is, fmt); if (! fmt.discard && ! is.fail ()) switch (fmt.bitwidth) { case 64: switch (fmt.type) { case 'd': { octave_int64 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; case 'u': { octave_uint64 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; } break; case 32: switch (fmt.type) { case 'd': { octave_int32 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; case 'u': { octave_uint32 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; } break; case 16: if (fmt.type == 'd') { octave_int16 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } else { octave_uint16 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; case 8: if (fmt.type == 'd') { octave_int8 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } else { octave_uint8 vv = v; ov.internal_rep ()->fast_elem_insert (row(0), vv); } break; } } if (is.fail () & ! fmt.discard) ov = do_cat_op (ov, empty_value, row); } else { std::string vv (" "); // initial buffer. Grows as needed switch (fmt.type) { case 's': scan_string (is, fmt, vv); break; case 'q': scan_qstring (is, fmt, vv); break; case 'c': scan_cstring (is, fmt, vv); break; case '[': scan_bracket (is, fmt.char_class.c_str (), vv); break; case '^': scan_caret (is, fmt.char_class.c_str (), vv); break; } if (! fmt.discard) ov.internal_rep ()->fast_elem_insert (row (0), Cell (octave_value (vv))); // FIXME: why does failbit get set at EOF, instead of eofbit? if (! vv.empty ()) is.clear (is.rdstate () & ~std::ios_base::failbit); } is.field_done (); } // Read data corresponding to the entire format string once, placing the // values in row ROW of retval. int textscan::read_format_once (delimited_stream& is, textscan_format_list& fmt_list, std::list<octave_value>& retval, Array<octave_idx_type> row, int& done_after) { const textscan_format_elt *elem = fmt_list.first (); std::list<octave_value>::iterator out = retval.begin (); bool no_conversions = true; bool done = false; bool conversion_failed = false; // Record for ReturnOnError bool nothing_worked = true; octave_quit (); for (size_t i = 0; i < fmt_list.numel (); i++) { bool this_conversion_failed = false; // Clear fail of previous numeric conversions. is.clear (); switch (elem->type) { case 'C': case 'D': warning ("%s: conversion %c not yet implemented", who.c_str (), elem->type); break; case 'u': case 'd': case 'f': case 'n': case 's': case '[': case '^': case 'q': case 'c': scan_one (is, *elem, *out, row); break; case textscan_format_elt::literal_conversion : match_literal (is, *elem); break; default: error ("Unknown format element '%c'", elem->type); } if (! is.fail ()) { if (! elem->discard) no_conversions = false; } else { is.clear (is.rdstate () & ~std::ios::failbit); if (! is.eof () && ~is_delim (is.peek ())) this_conversion_failed = true; } if (! elem->discard) out++; elem = fmt_list.next (); char *pos = is.tellg (); // FIXME: these conversions "ignore delimiters". Should they include // delimiters at the start of the conversion, or can those be skipped? if (elem->type != textscan_format_elt::literal_conversion // && elem->type != '[' && elem->type != '^' && elem->type != 'c' ) skip_delim (is); if (is.eof ()) { if (! done) done_after = i+1; // note EOF, but process others to get empty_val. done = true; } if (this_conversion_failed) { if (is.tellg () == pos && ! conversion_failed) { // done_after = first failure done_after = i; // note fail, but parse others to get empty_val conversion_failed = true; } else this_conversion_failed = false; } else if (! done && ! conversion_failed) nothing_worked = false; } if (done) is.setstate (std::ios::eofbit); return no_conversions + (is.eof () ? 2 : 0) + (conversion_failed ? 4 : 0) + (nothing_worked ? 8 : 0); } void textscan::parse_options (const octave_value_list& args, textscan_format_list& fmt_list) { int last = args.length (); int n = last; if (n & 1) error ("%s: %d parameters given, but only %d values", who.c_str (), n-n/2, n/2); delim_len = 1; bool have_delims = false; for (int i = 0; i < last; i += 2) { std::string param = args(i).xstring_value ("%s: Invalid parameter type <%s> for parameter %d", who.c_str (), args(i).type_name ().c_str (), i/2 + 1); std::transform (param.begin (), param.end (), param.begin (), ::tolower); if (param == "delimiter") { bool invalid = true; if (args(i+1).is_string ()) { invalid = false; have_delims = true; delims = args(i+1).string_value (); if (args(i+1).is_sq_string ()) delims = do_string_escapes (delims); } else if (args(i+1).is_cell ()) { invalid = false; delim_list = args(i+1).cell_value (); delim_table = " "; // non-empty, to flag non-default delim // Check that all elements are strings, and find max length for (int j = 0; j < delim_list.numel (); j++) { if (! delim_list(j).is_string ()) invalid = true; else { if (delim_list(j).is_sq_string ()) delim_list(j) = do_string_escapes (delim_list(j) .string_value ()); octave_idx_type len = delim_list(j).string_value () .length (); delim_len = std::max (static_cast<int> (len), delim_len); } } } if (invalid) error ("%s: Delimiters must be either a string or cell array of strings", who.c_str ()); } else if (param == "commentstyle") { if (args(i+1).is_string ()) { // check here for names like "C++", "C", "shell", ...? comment_style = Cell (args(i+1)); } else if (args(i+1).is_cell ()) { comment_style = args(i+1).cell_value (); int len = comment_style.numel (); if ((len >= 1 && ! comment_style (0).is_string ()) || (len >= 2 && ! comment_style (1).is_string ()) || (len >= 3)) error ("%s: CommentStyle must be either a string or cell array of one or two strings", who.c_str ()); } else error ("%s: CommentStyle must be either a string or cell array of one or two strings", who.c_str ()); // How far ahead do we need to look to detect an open comment // and which character do we look for? if (comment_style.numel () >= 1) { comment_len = comment_style (0).string_value ().size (); comment_char = comment_style (0).string_value ()[0]; } } else if (param == "treatasempty") { bool invalid = false; if (args(i+1).is_string ()) { treat_as_empty = Cell (args(i+1)); treat_as_empty_len = args(i+1).string_value ().size (); } else if (args(i+1).is_cell ()) { treat_as_empty = args(i+1).cell_value (); for (int j = 0; j < treat_as_empty.numel (); j++) if (! treat_as_empty (j).is_string ()) invalid = true; else { int k = treat_as_empty (j).string_value ().size (); if (k > treat_as_empty_len) treat_as_empty_len = k; } } if (invalid) error ("%s: TreatAsEmpty must be either a string or cell array of one or two strings", who.c_str ()); // FIXME: Ensure none is a prefix of a later one. Sort by length? } else if (param == "collectoutput") { collect_output = args(i+1).xbool_value ("%s: CollectOutput must be logical or numeric", who.c_str ()); } else if (param == "emptyvalue") { empty_value = args(i+1).xscalar_value ("%s: EmptyValue must be numeric", who.c_str ()); } else if (param == "headerlines") { header_lines = args(i+1).xscalar_value ("%s: HeaderLines must be numeric", who.c_str ()); } else if (param == "bufsize") { buffer_size = args(i+1).xscalar_value ("%s: BufSize must be numeric", who.c_str ()); } else if (param == "multipledelimsasone") { multiple_delims_as_one = args(i+1).xbool_value ("%s: MultipleDelimsAsOne must be logical or numeric", who.c_str ()); } else if (param == "returnonerror") { return_on_error = args(i+1).xbool_value ("%s: ReturnOnError must be logical or numeric", who.c_str ()); } else if (param == "whitespace") { whitespace = args(i+1).xstring_value ("%s: Whitespace must be a character string", who.c_str ()); } else if (param == "expchars") { exp_chars = args(i+1).xstring_value ("%s: ExpChars must be a character string", who.c_str ()); default_exp = false; } else if (param == "endofline") { bool valid = true; std::string s = args(i+1).xstring_value ("%s: EndOfLine must be at most one character or '\\r\\n'", who.c_str ()); if (args(i+1).is_sq_string ()) s = do_string_escapes (s); int l = s.length (); if (l == 0) eol1 = eol2 = -2; else if (l == 1) eol1 = eol2 = s.c_str ()[0]; else if (l == 2) { eol1 = s.c_str ()[0]; eol2 = s.c_str ()[1]; if (eol1 != '\r' || eol2 != '\n') // Why limit it? valid = false; } else valid = false; if (! valid) error ("%s: EndOfLine must be at most one character or '\\r\\n'", who.c_str ()); } else error ("%s: unrecognized option '%s'", who.c_str (), param.c_str ()); } whitespace_table = std::string (256, '\0'); for (unsigned int i = 0; i < whitespace.length (); i++) whitespace_table[whitespace[i]] = '1'; // For Matlab compatibility, add 0x20 to whitespace, unless // whitespace is explicitly ignored. if (! (whitespace.empty () && fmt_list.has_string)) whitespace_table[' '] = '1'; // Create look-up table of delimiters, based on 'delimiter' delim_table = std::string (256, '\0'); if (eol1 >= 0 && eol1 < 256) delim_table[eol1] = '1'; // EOL is always a delimiter if (eol2 >= 0 && eol2 < 256) delim_table[eol2] = '1'; // EOL is always a delimiter if (! have_delims) for (unsigned int i = 0; i < 256; i++) { if (isspace (i)) delim_table[i] = '1'; } else for (unsigned int i = 0; i < delims.length (); i++) delim_table[delims[i]] = '1'; } // Skip comments, and characters specified by the "Whitespace" option. // If EOLstop == true, don't skip end of line. int textscan::skip_whitespace (delimited_stream& is, bool EOLstop) { int c1 = std::istream::traits_type::eof (); bool found_comment = false; do { found_comment = false; int prev = -1; while (is && (c1 = is.get_undelim ()) != std::istream::traits_type::eof () && ( ( (c1 == eol1 || c1 == eol2) && ++lines && ! EOLstop) || isspace (c1))) { if (prev == eol1 && eol1 != eol2 && c1 == eol2) lines--; prev = c1; } if (c1 == comment_char) // see if we match an open comment { // save stream state in case we have to restore it char *pos = is.tellg (); std::ios::iostate state = is.rdstate (); std::string tmp (comment_len, '\0'); char *look = is.read (&tmp[0], comment_len-1, pos); // already read first char if (is && ! strncmp (comment_style(0).string_value ().substr (1) .c_str (), look, comment_len-1)) { found_comment = true; std::string dummy; if (comment_style.numel () == 1) // skip to end of line { std::string eol (3, '\0'); eol[0] = eol1; eol[1] = eol2; scan_caret (is, eol, dummy); c1 = is.get_undelim (); if (c1 == eol1 && eol1 != eol2 && is.peek_undelim () == eol2) is.get_undelim (); lines++; } else // matching pair { std::string end_c = comment_style(1).string_value (); // last char of end-comment sequence std::string last = end_c.substr (end_c.size () - 1); std::string may_match (""); do { // find sequence ending with last char scan_caret (is, last, dummy); is.get_undelim (); // (read LAST itself) may_match = may_match + dummy + last; if (may_match.length () > end_c.length ()) { size_t start = may_match.length () - end_c.length (); may_match = may_match.substr (start); } } while (may_match != end_c && is && ! is.eof ()); } } else // wasn't really a comment; restore state { is.clear (state); is.seekg (pos); } } } while (found_comment); if (c1 != std::istream::traits_type::eof ()) is.putback (c1); return c1; } // See if the next few characters match one of the strings in target. // For efficiency, MAX_LEN is the cached longest length of any target. // Return -1 if none is found, or the index of the match. int textscan::lookahead (delimited_stream& is, const Cell& targets, int max_len, bool case_sensitive) const { // target strings may be different sizes. // Read ahead longest, put it all back, then re-read the string // that matches. char *pos = is.tellg (); std::string tmp (max_len, '\0'); char *look = is.read (&tmp[0], tmp.size (), pos); is.clear (); is.seekg (pos); // reset to position before look-ahead // FIXME: pos may be corrupted by is.read int i; int (*compare)(const char *, const char *, size_t); compare = case_sensitive ? strncmp : strncasecmp; for (i = 0; i < targets.numel (); i++) { std::string s = targets (i).string_value (); if (! (*compare) (s.c_str (), look, s.size ())) { is.read (&tmp[0], s.size (), pos); // read just the right amount break; } } if (i == targets.numel ()) i = -1; return i; } // Skip delimiters -- multiple if MultipleDelimsAsOne specified. int textscan::skip_delim (delimited_stream& is) { int c1 = skip_whitespace (is, true); // 'true': stop once EOL is read if (delim_list.numel () == 0) // single character delimiter { if (is_delim (c1) || c1 == eol1 || c1 == eol2) { is.get (); if (c1 == eol1 && is.peek_undelim () == eol2) is.get_undelim (); // if \r\n, skip the \n too. if (multiple_delims_as_one) { int prev = -1; // skip multiple delims. // Increment lines for each end-of-line seen; for \r\n, decrement while (is && ((c1 = is.get_undelim ()) != std::istream::traits_type::eof ()) && (((c1 == eol1 || c1 == eol2) && ++lines) || isspace (c1) || is_delim (c1))) { if (prev == eol1 && eol1 != eol2 && c1 == eol2) lines--; prev = c1; } if (c1 != std::istream::traits_type::eof ()) is.putback (c1); } } } else // multi-character delimiter { int first_match; if (c1 == eol1 || c1 == eol2 || (-1 != (first_match = lookahead (is, delim_list, delim_len)))) { if (c1 == eol1) { is.get_undelim (); if (is.peek_undelim () == eol2) is.get_undelim (); } else if (c1 == eol2) { is.get_undelim (); } if (multiple_delims_as_one) { int prev = -1; // skip multiple delims. // Increment lines for each end-of-line seen; for \r\n, decrement while (is && ((c1 = skip_whitespace (is, true)) != std::istream::traits_type::eof ()) && (((c1 == eol1 || c1 == eol2) && ++lines) || -1 != lookahead (is, delim_list, delim_len))) { if (prev == eol1 && eol1 != eol2 && c1 == eol2) lines--; prev = c1; } } } } return c1; } // Read in as much of the input as coincides with the literal in the // format string. Return "true" if the entire literal is matched, else // false (and set failbit). bool textscan::match_literal (delimited_stream& is, const textscan_format_elt& fmt) { // "false" -> treat EOL as normal space // since a delimiter at the start of a line is a mismatch, not empty field skip_whitespace (is, false); for (unsigned int i = 0; i < fmt.width; i++) { int ch = is.get_undelim (); if (ch != fmt.text[i]) { if (ch != std::istream::traits_type::eof ()) is.putback (ch); is.setstate (std::ios::failbit); return false; } } return true; } } void octave_base_stream::error (const std::string& msg) { fail = true; errmsg = msg; } void octave_base_stream::error (const std::string& who, const std::string& msg) { fail = true; errmsg = who + ": " + msg; } void octave_base_stream::clear (void) { fail = false; errmsg = ""; } void octave_base_stream::clearerr (void) { std::istream *is = input_stream (); std::ostream *os = output_stream (); if (is) is->clear (); if (os) os->clear (); } // Functions that are defined for all input streams (input streams // are those that define is). std::string octave_base_stream::do_gets (octave_idx_type max_len, bool& err, bool strip_newline, const std::string& who) { if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); std::string retval; err = false; std::istream *isp = input_stream (); if (! isp) { err = true; invalid_operation (who, "reading"); } else { std::istream& is = *isp; std::ostringstream buf; int c = 0; int char_count = 0; if (max_len != 0) { while (is && (c = is.get ()) != std::istream::traits_type::eof ()) { char_count++; // Handle CRLF, CR, or LF as line ending. if (c == '\r') { if (! strip_newline) buf << static_cast<char> (c); c = is.get (); if (c != std::istream::traits_type::eof ()) { if (c == '\n') { char_count++; if (! strip_newline) buf << static_cast<char> (c); } else is.putback (c); } break; } else if (c == '\n') { if (! strip_newline) buf << static_cast<char> (c); break; } else buf << static_cast<char> (c); if (max_len > 0 && char_count == max_len) break; } } if (! is.eof () && char_count > 0) { // GAGME. Matlab seems to check for EOF even if the last character // in a file is a newline character. This is NOT what the // corresponding C-library functions do. int disgusting_compatibility_hack = is.get (); if (! is.eof ()) is.putback (disgusting_compatibility_hack); } if (is.good () || (is.eof () && char_count > 0)) retval = buf.str (); else { err = true; if (is.eof () && char_count == 0) error (who, "at end of file"); else error (who, "read error"); } } return retval; } std::string octave_base_stream::getl (octave_idx_type max_len, bool& err, const std::string& who) { return do_gets (max_len, err, true, who); } std::string octave_base_stream::gets (octave_idx_type max_len, bool& err, const std::string& who) { return do_gets (max_len, err, false, who); } off_t octave_base_stream::skipl (off_t num, bool& err, const std::string& who) { if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); off_t cnt = -1; err = false; std::istream *isp = input_stream (); if (! isp) { err = true; invalid_operation (who, "reading"); } else { std::istream& is = *isp; int c = 0; int lastc = -1; cnt = 0; while (is && (c = is.get ()) != std::istream::traits_type::eof ()) { // Handle CRLF, CR, or LF as line ending. if (c == '\r' || (c == '\n' && lastc != '\r')) { if (++cnt == num) break; } lastc = c; } // Maybe eat the following \n if \r was just met. if (c == '\r' && is.peek () == '\n') is.get (); if (is.bad ()) { err = true; error (who, "read error"); } if (err) cnt = -1; } return cnt; } template <typename T> std::istream& octave_scan_1 (std::istream& is, const scanf_format_elt& fmt, T* valptr) { T value = T (); switch (fmt.type) { case 'o': is >> std::oct >> value >> std::dec; break; case 'x': is >> std::hex >> value >> std::dec; break; case 'i': { int c1 = std::istream::traits_type::eof (); while (is && (c1 = is.get ()) != std::istream::traits_type::eof () && isspace (c1)) ; // skip whitespace if (c1 != std::istream::traits_type::eof ()) { if (c1 == '0') { int c2 = is.peek (); if (c2 == 'x' || c2 == 'X') { is.ignore (); if (std::isxdigit (is.peek ())) is >> std::hex >> value >> std::dec; else value = 0; } else { if (c2 == '0' || c2 == '1' || c2 == '2' || c2 == '3' || c2 == '4' || c2 == '5' || c2 == '6' || c2 == '7') is >> std::oct >> value >> std::dec; else if (c2 == '8' || c2 == '9') { // FIXME: Would like to set error state on octave // stream. See bug #46493. But only std::istream is // input to fcn. // error ("internal failure to match octal format"); value = 0; } else value = 0; } } else { is.putback (c1); is >> value; } } } break; default: is >> value; break; } // If conversion produces an integer that overflows, failbit is set but // value is non-zero. We want to treat this case as success, so clear // failbit from the stream state to keep going. // FIXME: Maybe set error state on octave stream as above? Matlab does // *not* indicate an error message on overflow. if ((is.rdstate () & std::ios::failbit) && value != T ()) is.clear (is.rdstate () & ~std::ios::failbit); // Only copy the converted value if the stream is in a state where we // want to continue reading. if (! (is.rdstate () & std::ios::failbit)) *valptr = value; return is; } template <typename T> std::istream& octave_scan (std::istream& is, const scanf_format_elt& fmt, T* valptr) { if (fmt.width) { // Limit input to fmt.width characters by reading into a // temporary stringstream buffer. std::string tmp; is.width (fmt.width); is >> tmp; std::istringstream ss (tmp); octave_scan_1 (ss, fmt, valptr); } else octave_scan_1 (is, fmt, valptr); return is; } // Note that this specialization is only used for reading characters, not // character strings. See BEGIN_S_CONVERSION for details. template <> std::istream& octave_scan<> (std::istream& is, const scanf_format_elt& /* fmt */, char* valptr) { return is >> valptr; } template <> std::istream& octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double* valptr) { double& ref = *valptr; switch (fmt.type) { case 'e': case 'f': case 'g': { int c1 = std::istream::traits_type::eof (); while (is && (c1 = is.get ()) != std::istream::traits_type::eof () && isspace (c1)) ; // skip whitespace if (c1 != std::istream::traits_type::eof ()) { is.putback (c1); ref = octave_read_value<double> (is); } } break; default: panic_impossible (); break; } return is; } template <typename T> void do_scanf_conv (std::istream& is, const scanf_format_elt& fmt, T valptr, Matrix& mval, double *data, octave_idx_type& idx, octave_idx_type& conversion_count, octave_idx_type nr, octave_idx_type max_size, bool discard) { octave_scan (is, fmt, valptr); if (! is) return; if (idx == max_size && ! discard) { max_size *= 2; if (nr > 0) mval.resize (nr, max_size / nr, 0.0); else mval.resize (max_size, 1, 0.0); data = mval.fortran_vec (); } if (! discard) { conversion_count++; data[idx++] = *(valptr); } } template void do_scanf_conv (std::istream&, const scanf_format_elt&, double*, Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); #define DO_WHITESPACE_CONVERSION() \ do \ { \ int c = std::istream::traits_type::eof (); \ \ while (is && (c = is.get ()) != std::istream::traits_type::eof () \ && isspace (c)) \ { /* skip whitespace */ } \ \ if (c != std::istream::traits_type::eof ()) \ is.putback (c); \ } \ while (0) #define DO_LITERAL_CONVERSION() \ do \ { \ int c = std::istream::traits_type::eof (); \ \ int n = strlen (fmt); \ int i = 0; \ \ while (i < n && is && (c = is.get ()) != std::istream::traits_type::eof ()) \ { \ if (c == static_cast<unsigned char> (fmt[i])) \ { \ i++; \ continue; \ } \ else \ { \ is.putback (c); \ break; \ } \ } \ \ if (i != n) \ is.setstate (std::ios::failbit); \ } \ while (0) #define DO_PCT_CONVERSION() \ do \ { \ int c = is.get (); \ \ if (c != std::istream::traits_type::eof ()) \ { \ if (c != '%') \ { \ is.putback (c); \ is.setstate (std::ios::failbit); \ } \ } \ else \ is.setstate (std::ios::failbit); \ } \ while (0) #define BEGIN_C_CONVERSION() \ is.unsetf (std::ios::skipws); \ \ int width = elt->width ? elt->width : 1; \ \ std::string tmp (width, '\0'); \ \ int c = std::istream::traits_type::eof (); \ int n = 0; \ \ while (is && n < width \ && (c = is.get ()) != std::istream::traits_type::eof ()) \ tmp[n++] = static_cast<char> (c); \ \ if (n > 0 && c == std::istream::traits_type::eof ()) \ is.clear (); \ \ tmp.resize (n) // 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; \ \ std::string tmp; \ \ do \ { \ if (width) \ { \ tmp = std::string (width, '\0'); \ \ int c = std::istream::traits_type::eof (); \ \ int n = 0; \ \ while (is && (c = is.get ()) != std::istream::traits_type::eof ()) \ { \ if (! isspace (c)) \ { \ tmp[n++] = static_cast<char> (c); \ break; \ } \ } \ \ while (is && n < width \ && (c = is.get ()) != std::istream::traits_type::eof ()) \ { \ if (isspace (c)) \ { \ is.putback (c); \ break; \ } \ else \ tmp[n++] = static_cast<char> (c); \ } \ \ if (n > 0 && c == std::istream::traits_type::eof ()) \ is.clear (); \ \ tmp.resize (n); \ } \ else \ { \ is >> std::ws >> tmp; \ } \ } \ while (0) // This format must match a nonempty sequence of characters. #define BEGIN_CHAR_CLASS_CONVERSION() \ int width = elt->width; \ \ std::string tmp; \ \ do \ { \ if (! width) \ width = std::numeric_limits<int>::max (); \ \ std::ostringstream buf; \ \ std::string char_class = elt->char_class; \ \ int c = std::istream::traits_type::eof (); \ \ if (elt->type == '[') \ { \ int chars_read = 0; \ while (is && chars_read++ < width \ && (c = is.get ()) != std::istream::traits_type::eof () \ && char_class.find (c) != std::string::npos) \ buf << static_cast<char> (c); \ } \ else \ { \ int chars_read = 0; \ while (is && chars_read++ < width \ && (c = is.get ()) != std::istream::traits_type::eof () \ && char_class.find (c) == std::string::npos) \ buf << static_cast<char> (c); \ } \ \ if (width == std::numeric_limits<int>::max () \ && c != std::istream::traits_type::eof ()) \ is.putback (c); \ \ tmp = buf.str (); \ \ if (tmp.empty ()) \ is.setstate (std::ios::failbit); \ else if (c == std::istream::traits_type::eof ()) \ is.clear (); \ \ } \ while (0) #define FINISH_CHARACTER_CONVERSION() \ do \ { \ width = tmp.length (); \ \ if (is) \ { \ int i = 0; \ \ if (! discard) \ { \ conversion_count++; \ \ while (i < width) \ { \ if (data_index == max_size) \ { \ max_size *= 2; \ \ if (all_char_conv) \ { \ if (one_elt_size_spec) \ mval.resize (1, max_size, 0.0); \ else if (nr > 0) \ mval.resize (nr, max_size / nr, 0.0); \ else \ panic_impossible (); \ } \ else if (nr > 0) \ mval.resize (nr, max_size / nr, 0.0); \ else \ mval.resize (max_size, 1, 0.0); \ \ data = mval.fortran_vec (); \ } \ \ data[data_index++] = tmp[i++]; \ } \ } \ } \ } \ while (0) octave_value octave_base_stream::do_scanf (scanf_format_list& fmt_list, octave_idx_type nr, octave_idx_type nc, bool one_elt_size_spec, octave_idx_type& conversion_count, const std::string& who) { if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); octave_value retval = Matrix (); conversion_count = 0; octave_idx_type nconv = fmt_list.num_conversions (); octave_idx_type data_index = 0; if (nr == 0 || nc == 0) { if (one_elt_size_spec) nc = 0; return Matrix (nr, nc, 0.0); } std::istream *isp = input_stream (); bool all_char_conv = fmt_list.all_character_conversions (); Matrix mval; double *data = 0; octave_idx_type max_size = 0; octave_idx_type max_conv = 0; octave_idx_type final_nr = 0; octave_idx_type final_nc = 0; if (all_char_conv) { // Any of these could be resized later (if we have %s conversions, // we may read more than one element for each conversion). if (one_elt_size_spec) { max_size = 512; mval.resize (1, max_size, 0.0); if (nr > 0) max_conv = nr; } else if (nr > 0) { if (nc > 0) { mval.resize (nr, nc, 0.0); max_size = max_conv = nr * nc; } else { mval.resize (nr, 32, 0.0); max_size = nr * 32; } } else panic_impossible (); } else if (nr > 0) { if (nc > 0) { // Will not resize later. mval.resize (nr, nc, 0.0); max_size = nr * nc; max_conv = max_size; } else { // Maybe resize later. mval.resize (nr, 32, 0.0); max_size = nr * 32; } } else { // Maybe resize later. mval.resize (32, 1, 0.0); max_size = 32; } data = mval.fortran_vec (); if (isp) { std::istream& is = *isp; const scanf_format_elt *elt = fmt_list.first (); std::ios::fmtflags flags = is.flags (); octave_idx_type trips = 0; octave_idx_type num_fmt_elts = fmt_list.length (); for (;;) { octave_quit (); if (elt) { if (elt->type == scanf_format_elt::null || (! (elt->type == scanf_format_elt::whitespace_conversion || elt->type == scanf_format_elt::literal_conversion || elt->type == '%') && max_conv > 0 && conversion_count == max_conv)) { // We are done, either because we have reached the end of the // format string and are not cycling through the format again // or because we've converted all the values that have been // requested and the next format element is a conversion. // Determine final array size and exit. if (all_char_conv && one_elt_size_spec) { final_nr = 1; final_nc = data_index; } else { final_nr = nr; final_nc = (data_index - 1) / nr + 1; } break; } else if (data_index == max_size) { max_size *= 2; if (all_char_conv) { if (one_elt_size_spec) mval.resize (1, max_size, 0.0); else if (nr > 0) mval.resize (nr, max_size / nr, 0.0); else panic_impossible (); } else if (nr > 0) mval.resize (nr, max_size / nr, 0.0); else mval.resize (max_size, 1, 0.0); data = mval.fortran_vec (); } const char *fmt = elt->text; bool discard = elt->discard; switch (elt->type) { case scanf_format_elt::whitespace_conversion: DO_WHITESPACE_CONVERSION (); break; case scanf_format_elt::literal_conversion: DO_LITERAL_CONVERSION (); break; case '%': DO_PCT_CONVERSION (); break; case 'd': case 'i': { switch (elt->modifier) { case 'h': { int16_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; case 'l': { int64_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; default: { int32_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; } } break; case 'o': case 'u': case 'x': { switch (elt->modifier) { case 'h': { uint16_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; case 'l': { uint64_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; default: { uint32_t tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; } } break; case 'e': case 'f': case 'g': { double tmp; do_scanf_conv (is, *elt, &tmp, mval, data, data_index, conversion_count, nr, max_size, discard); } break; case 'c': { BEGIN_C_CONVERSION (); FINISH_CHARACTER_CONVERSION (); is.setf (flags); } break; case 's': { BEGIN_S_CONVERSION (); FINISH_CHARACTER_CONVERSION (); } break; case '[': case '^': { BEGIN_CHAR_CLASS_CONVERSION (); FINISH_CHARACTER_CONVERSION (); } break; case 'p': error ("%s: unsupported format specifier", who.c_str ()); break; default: error ("%s: internal format error", who.c_str ()); break; } if (! ok ()) { break; } else if (! is) { if (all_char_conv) { if (one_elt_size_spec) { final_nr = 1; final_nc = data_index; } else if (data_index > nr) { final_nr = nr; final_nc = (data_index - 1) / nr + 1; } else { final_nr = data_index; final_nc = 1; } } else if (nr > 0) { if (data_index > nr) { final_nr = nr; final_nc = (data_index - 1) / nr + 1; } else { final_nr = data_index; final_nc = 1; } } else { final_nr = data_index; final_nc = 1; } // If it looks like we have a matching failure, then // reset the failbit in the stream state. if (is.rdstate () & std::ios::failbit) is.clear (is.rdstate () & (~std::ios::failbit)); // FIXME: is this the right thing to do? if (octave::application::interactive () && ! octave::application::forced_interactive () && name () == "stdin") { is.clear (); // Skip to end of line. bool err; do_gets (-1, err, false, who); } break; } } else { error ("%s: internal format error", who.c_str ()); break; } if (nconv == 0 && ++trips == num_fmt_elts) { if (all_char_conv && one_elt_size_spec) { final_nr = 1; final_nc = data_index; } else { final_nr = nr; final_nc = (data_index - 1) / nr + 1; } break; } else { // Cycle through the format list more than once if we have some // conversions to make and we haven't reached the limit on the // number of values to convert (possibly because there is no // specified limit). elt = fmt_list.next (nconv > 0 && (max_conv == 0 || conversion_count < max_conv)); } } } if (ok ()) { mval.resize (final_nr, final_nc, 0.0); retval = mval; if (all_char_conv) retval = retval.convert_to_str (false, true); } return retval; } octave_value octave_base_stream::scanf (const std::string& fmt, const Array<double>& size, octave_idx_type& conversion_count, const std::string& who) { octave_value retval = Matrix (); conversion_count = 0; std::istream *isp = input_stream (); if (! isp) invalid_operation (who, "reading"); else { scanf_format_list fmt_list (fmt); if (fmt_list.num_conversions () == -1) ::error ("%s: invalid format specified", who.c_str ()); octave_idx_type nr = -1; octave_idx_type nc = -1; bool one_elt_size_spec; get_size (size, nr, nc, one_elt_size_spec, who); retval = do_scanf (fmt_list, nr, nc, one_elt_size_spec, conversion_count, who); } return retval; } bool octave_base_stream::do_oscanf (const scanf_format_elt *elt, octave_value& retval, const std::string& who) { std::istream *isp = input_stream (); if (! isp) return false; bool quit = false; std::istream& is = *isp; std::ios::fmtflags flags = is.flags (); if (elt) { const char *fmt = elt->text; bool discard = elt->discard; switch (elt->type) { case scanf_format_elt::whitespace_conversion: DO_WHITESPACE_CONVERSION (); break; case scanf_format_elt::literal_conversion: DO_LITERAL_CONVERSION (); break; case '%': { DO_PCT_CONVERSION (); if (! is) quit = true; } break; case 'd': case 'i': { int tmp; if (octave_scan (is, *elt, &tmp)) { if (! discard) retval = tmp; } else quit = true; } break; case 'o': case 'u': case 'x': { long int tmp; if (octave_scan (is, *elt, &tmp)) { if (! discard) retval = tmp; } else quit = true; } break; case 'e': case 'f': case 'g': { double tmp; if (octave_scan (is, *elt, &tmp)) { if (! discard) retval = tmp; } else quit = true; } break; case 'c': { BEGIN_C_CONVERSION (); if (! discard) retval = tmp; if (! is) quit = true; is.setf (flags); } break; case 's': { BEGIN_S_CONVERSION (); if (! discard) retval = tmp; if (! is) quit = true; } break; case '[': case '^': { BEGIN_CHAR_CLASS_CONVERSION (); if (! discard) retval = tmp; if (! is) quit = true; } break; case 'p': error ("%s: unsupported format specifier", who.c_str ()); break; default: error ("%s: internal format error", who.c_str ()); break; } } if (ok () && is.fail ()) { error ("%s: read error", who.c_str ()); // FIXME: is this the right thing to do? if (octave::application::interactive () && ! octave::application::forced_interactive () && name () == "stdin") { // Skip to end of line. bool err; do_gets (-1, err, false, who); } } return quit; } octave_value_list octave_base_stream::oscanf (const std::string& fmt, const std::string& who) { octave_value_list retval; std::istream *isp = input_stream (); if (! isp) invalid_operation (who, "reading"); else { std::istream& is = *isp; scanf_format_list fmt_list (fmt); octave_idx_type nconv = fmt_list.num_conversions (); if (nconv == -1) ::error ("%s: invalid format specified", who.c_str ()); is.clear (); octave_idx_type len = fmt_list.length (); retval.resize (nconv+2, Matrix ()); const scanf_format_elt *elt = fmt_list.first (); int num_values = 0; bool quit = false; for (octave_idx_type i = 0; i < len; i++) { octave_value tmp; quit = do_oscanf (elt, tmp, who); if (quit) break; else { if (tmp.is_defined ()) retval(num_values++) = tmp; if (! ok ()) break; elt = fmt_list.next (nconv > 0); } } retval(nconv) = num_values; int err_num; retval(nconv+1) = error (false, err_num); if (! quit) { // Pick up any trailing stuff. if (ok () && len > nconv) { octave_value tmp; elt = fmt_list.next (); do_oscanf (elt, tmp, who); } } } return retval; } octave_value octave_base_stream::do_textscan (const std::string& fmt, octave_idx_type ntimes, const octave_value_list& options, const std::string& who, octave_idx_type& read_count) { if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); octave_value retval = Cell (dim_vector (1, 1), Matrix (0, 1)); std::istream *isp = input_stream (); if (! isp) invalid_operation (who, "reading"); else { octave::textscan scanner (who); retval = scanner.scan (*isp, fmt, ntimes, options, read_count); } return retval; } // Functions that are defined for all output streams // (output streams are those that define os). int octave_base_stream::flush (void) { int retval = -1; std::ostream *os = output_stream (); if (! os) invalid_operation ("fflush", "writing"); else { os->flush (); if (os->good ()) retval = 0; } return retval; } class printf_value_cache { public: enum state { ok, conversion_error }; printf_value_cache (const octave_value_list& args, const std::string& who) : values (args), val_idx (0), elt_idx (0), n_vals (values.length ()), n_elts (0), have_data (false), curr_state (ok) { for (octave_idx_type i = 0; i < values.length (); i++) { octave_value val = values(i); if (val.is_map () || val.is_cell () || val.is_object ()) err_wrong_type_arg (who, val); } } ~printf_value_cache (void) { } // Get the current value as a double and advance the internal pointer. octave_value get_next_value (char type = 0); // Get the current value as an int and advance the internal pointer. int int_value (void); operator bool () const { return (curr_state == ok); } bool exhausted (void) { return (val_idx >= n_vals); } private: const octave_value_list values; int val_idx; int elt_idx; int n_vals; int n_elts; bool have_data; octave_value curr_val; state curr_state; // Must create value cache with values! printf_value_cache (void); // No copying! printf_value_cache (const printf_value_cache&); printf_value_cache& operator = (const printf_value_cache&); }; octave_value printf_value_cache::get_next_value (char type) { octave_value retval; if (exhausted ()) curr_state = conversion_error; while (! exhausted ()) { if (! have_data) { curr_val = values (val_idx); elt_idx = 0; n_elts = curr_val.numel (); have_data = true; } if (elt_idx < n_elts) { if (type == 's') { if (curr_val.is_string ()) { dim_vector dv (1, curr_val.numel ()); octave_value tmp = curr_val.reshape (dv); std::string sval = tmp.string_value (); retval = sval.substr (elt_idx); // We've consumed the rest of the value. elt_idx = n_elts; } else { // Convert to character string while values are // integers in the range [0 : char max] const NDArray val = curr_val.array_value (); octave_idx_type idx = elt_idx; for (; idx < n_elts; idx++) { double dval = val(idx); if (octave::math::x_nint (dval) != dval || dval < 0 || dval > 255) break; } octave_idx_type n = idx - elt_idx; if (n > 0) { std::string sval (n, '\0'); for (octave_idx_type i = 0; i < n; i++) sval[i] = val(elt_idx++); retval = sval; } else retval = curr_val.fast_elem_extract (elt_idx++); } } else { retval = curr_val.fast_elem_extract (elt_idx++); if (type == 'c' && ! retval.is_string ()) { double dval = retval.double_value (); if (octave::math::x_nint (dval) == dval && dval >= 0 && dval < 256) retval = static_cast<char> (dval); } } if (elt_idx >= n_elts) { elt_idx = 0; val_idx++; have_data = false; } break; } else { val_idx++; have_data = false; if (n_elts == 0) { if (elt_idx == 0 && (type == 's' || type == 'c')) { retval = ""; break; } if (exhausted ()) curr_state = conversion_error; } } } return retval; } int printf_value_cache::int_value (void) { int retval = 0; octave_value val = get_next_value (); double dval = val.double_value (true); if (octave::math::x_nint (dval) == dval) retval = octave::math::nint (dval); else curr_state = conversion_error; return retval; } // Ugh again and again. template <typename T> int do_printf_conv (std::ostream& os, const char *fmt, int nsa, int sa_1, int sa_2, T arg, const std::string& who) { int retval = 0; switch (nsa) { case 2: retval = octave_format (os, fmt, sa_1, sa_2, arg); break; case 1: retval = octave_format (os, fmt, sa_1, arg); break; case 0: retval = octave_format (os, fmt, arg); break; default: ::error ("%s: internal error handling format", who.c_str ()); break; } return retval; } static size_t do_printf_string (std::ostream& os, const printf_format_elt *elt, int nsa, int sa_1, int sa_2, const std::string& arg, const std::string& who) { if (nsa > 2) ::error ("%s: internal error handling format", who.c_str ()); std::string flags = elt->flags; bool left = flags.find ('-') != std::string::npos; size_t len = arg.length (); size_t fw = nsa > 0 ? sa_1 : (elt->fw == -1 ? len : elt->fw); size_t prec = nsa > 1 ? sa_2 : (elt->prec == -1 ? len : elt->prec); os << std::setw (fw) << (left ? std::left : std::right) << (prec < len ? arg.substr (0, prec) : arg); return len > fw ? len : fw; } static bool is_nan_or_inf (const octave_value& val) { octave_value ov_isnan = val.isnan (); octave_value ov_isinf = val.isinf (); return (ov_isnan.is_true () || ov_isinf.is_true ()); } static bool ok_for_signed_int_conv (const octave_value& val) { uint64_t limit = std::numeric_limits<int64_t>::max (); if (val.is_string ()) return true; else if (val.is_integer_type ()) { if (val.is_uint64_type ()) { octave_uint64 ival = val.uint64_scalar_value (); if (ival.value () <= limit) return true; } else return true; } else { double dval = val.double_value (true); if (dval == octave::math::round (dval) && dval <= limit) return true; } return false; } static bool ok_for_unsigned_int_conv (const octave_value& val) { if (val.is_string ()) return true; else if (val.is_integer_type ()) { // Easier than dispatching here... octave_value ov_is_ge_zero = do_binary_op (octave_value::op_ge, val, octave_value (0.0)); return ov_is_ge_zero.is_true (); } else { double dval = val.double_value (true); uint64_t limit = std::numeric_limits<uint64_t>::max (); if (dval == octave::math::round (dval) && dval >= 0 && dval <= limit) return true; } return false; } static std::string switch_to_g_format (const printf_format_elt *elt) { std::string tfmt = elt->text; tfmt.replace (tfmt.rfind (elt->type), 1, "g"); return tfmt; } int octave_base_stream::do_numeric_printf_conv (std::ostream& os, const printf_format_elt *elt, int nsa, int sa_1, int sa_2, const octave_value& val, const std::string& who) { int retval = 0; const char *fmt = elt->text; if (is_nan_or_inf (val)) { double dval = val.double_value (); std::string tfmt = fmt; std::string::size_type i1, i2; tfmt.replace ((i1 = tfmt.rfind (elt->type)), 1, 1, 's'); if ((i2 = tfmt.rfind ('.')) != std::string::npos && i2 < i1) { tfmt.erase (i2, i1-i2); if (elt->prec == -2) nsa--; } const char *tval; if (lo_ieee_isinf (dval)) { if (elt->flags.find ('+') != std::string::npos) tval = (dval < 0 ? "-Inf" : "+Inf"); else tval = (dval < 0 ? "-Inf" : "Inf"); } else { if (elt->flags.find ('+') != std::string::npos) tval = (lo_ieee_is_NA (dval) ? "+NA" : "+NaN"); else tval = (lo_ieee_is_NA (dval) ? "NA" : "NaN"); } retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval, who); } else { static std::string llmod = sizeof (long) == sizeof (int64_t) ? "l" : "ll"; char type = elt->type; switch (type) { case 'd': case 'i': case 'c': if (ok_for_signed_int_conv (val)) { octave_int64 tval = val.int64_scalar_value (); // Insert "long" modifier. std::string tfmt = fmt; tfmt.replace (tfmt.rfind (type), 1, llmod + type); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval.value (), who); } else { std::string tfmt = switch_to_g_format (elt); double dval = val.double_value (true); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, dval, who); } break; case 'o': case 'x': case 'X': case 'u': if (ok_for_unsigned_int_conv (val)) { octave_uint64 tval = val.uint64_scalar_value (); // Insert "long" modifier. std::string tfmt = fmt; tfmt.replace (tfmt.rfind (type), 1, llmod + type); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval.value (), who); } else { std::string tfmt = switch_to_g_format (elt); double dval = val.double_value (true); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, dval, who); } break; case 'f': case 'e': case 'E': case 'g': case 'G': { double dval = val.double_value (true); retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, dval, who); } break; default: // Note: error is member fcn from octave_base_stream, not ::error. // This error does not halt execution so "return ..." must exist. error ("%s: invalid format specifier", who.c_str ()); return -1; break; } } return retval; } int octave_base_stream::do_printf (printf_format_list& fmt_list, const octave_value_list& args, const std::string& who) { int retval = 0; octave_idx_type nconv = fmt_list.num_conversions (); std::ostream *osp = output_stream (); if (! osp) invalid_operation (who, "writing"); else { std::ostream& os = *osp; const printf_format_elt *elt = fmt_list.first (); printf_value_cache val_cache (args, who); for (;;) { octave_quit (); if (! elt) ::error ("%s: internal error handling format", who.c_str ()); // NSA is the number of 'star' args to convert. int nsa = (elt->fw == -2) + (elt->prec == -2); int sa_1 = 0; int sa_2 = 0; if (nsa > 0) { sa_1 = val_cache.int_value (); if (! val_cache) break; else { if (nsa > 1) { sa_2 = val_cache.int_value (); if (! val_cache) break; } } } if (elt->type == '%') { os << "%"; retval++; } else if (elt->args == 0 && elt->text) { os << elt->text; retval += strlen (elt->text); } else if (elt->type == 's' || elt->type == 'c') { octave_value val = val_cache.get_next_value (elt->type); if (val_cache) { if (val.is_string ()) { std::string sval = val.string_value (); retval += do_printf_string (os, elt, nsa, sa_1, sa_2, sval, who); } else retval += do_numeric_printf_conv (os, elt, nsa, sa_1, sa_2, val, who); } else break; } else { octave_value val = val_cache.get_next_value (); if (val_cache) retval += do_numeric_printf_conv (os, elt, nsa, sa_1, sa_2, val, who); else break; } if (! os) { error ("%s: write error", who.c_str ()); break; } elt = fmt_list.next (nconv > 0 && ! val_cache.exhausted ()); if (! elt || (val_cache.exhausted () && elt->args > 0)) break; } } return retval; } int octave_base_stream::printf (const std::string& fmt, const octave_value_list& args, const std::string& who) { printf_format_list fmt_list (fmt); if (fmt_list.num_conversions () == -1) ::error ("%s: invalid format specified", who.c_str ()); return do_printf (fmt_list, args, who); } int octave_base_stream::puts (const std::string& s, const std::string& who) { int retval = -1; std::ostream *osp = output_stream (); if (! osp) invalid_operation (who, "writing"); else { std::ostream& os = *osp; os << s; if (! os) error ("%s: write error", who.c_str ()); else { // FIXME: why does this seem to be necessary? // Without it, output from a loop like // // for i = 1:100, fputs (stdout, "foo\n"); endfor // // doesn't seem to go to the pager immediately. os.flush (); if (os) retval = 0; else error ("%s: write error", who.c_str ()); } } return retval; } // Return current error message for this stream. std::string octave_base_stream::error (bool clear_err, int& err_num) { err_num = fail ? -1 : 0; std::string tmp = errmsg; if (clear_err) clear (); return tmp; } void octave_base_stream::invalid_operation (const std::string& who, const char *rw) { // Note: This calls the member fcn error, not ::error from error.h. error (who, std::string ("stream not open for ") + rw); } octave_stream::octave_stream (octave_base_stream *bs) : rep (bs) { if (rep) rep->count = 1; } octave_stream::~octave_stream (void) { if (rep && --rep->count == 0) delete rep; } octave_stream::octave_stream (const octave_stream& s) : rep (s.rep) { if (rep) rep->count++; } octave_stream& octave_stream::operator = (const octave_stream& s) { if (rep != s.rep) { if (rep && --rep->count == 0) delete rep; rep = s.rep; if (rep) rep->count++; } return *this; } int octave_stream::flush (void) { int retval = -1; if (stream_ok ()) retval = rep->flush (); return retval; } std::string octave_stream::getl (octave_idx_type max_len, bool& err, const std::string& who) { std::string retval; if (stream_ok ()) retval = rep->getl (max_len, err, who); return retval; } std::string octave_stream::getl (const octave_value& tc_max_len, bool& err, const std::string& who) { err = false; int conv_err = 0; int max_len = -1; if (tc_max_len.is_defined ()) { max_len = convert_to_valid_int (tc_max_len, conv_err); if (conv_err || max_len < 0) { err = true; ::error ("%s: invalid maximum length specified", who.c_str ()); } } return getl (max_len, err, who); } std::string octave_stream::gets (octave_idx_type max_len, bool& err, const std::string& who) { std::string retval; if (stream_ok ()) retval = rep->gets (max_len, err, who); return retval; } std::string octave_stream::gets (const octave_value& tc_max_len, bool& err, const std::string& who) { err = false; int conv_err = 0; int max_len = -1; if (tc_max_len.is_defined ()) { max_len = convert_to_valid_int (tc_max_len, conv_err); if (conv_err || max_len < 0) { err = true; ::error ("%s: invalid maximum length specified", who.c_str ()); } } return gets (max_len, err, who); } off_t octave_stream::skipl (off_t count, bool& err, const std::string& who) { off_t retval = -1; if (stream_ok ()) retval = rep->skipl (count, err, who); return retval; } off_t octave_stream::skipl (const octave_value& tc_count, bool& err, const std::string& who) { err = false; int conv_err = 0; int count = 1; if (tc_count.is_defined ()) { if (tc_count.is_scalar_type () && octave::math::isinf (tc_count.scalar_value ())) count = -1; else { count = convert_to_valid_int (tc_count, conv_err); if (conv_err || count < 0) { err = true; ::error ("%s: invalid number of lines specified", who.c_str ()); } } } return skipl (count, err, who); } int octave_stream::seek (off_t offset, int origin) { int status = -1; if (stream_ok ()) { clearerr (); // Find current position so we can return to it if needed. off_t orig_pos = rep->tell (); // Move to end of file. If successful, find the offset of the end. status = rep->seek (0, SEEK_END); if (status == 0) { off_t eof_pos = rep->tell (); if (origin == SEEK_CUR) { // Move back to original position, otherwise we will be seeking // from the end of file which is probably not the original // location. rep->seek (orig_pos, SEEK_SET); } // Attempt to move to desired position; may be outside bounds of // existing file. status = rep->seek (offset, origin); if (status == 0) { // Where are we after moving to desired position? off_t desired_pos = rep->tell (); // I don't think save_pos can be less than zero, // but we'll check anyway... if (desired_pos > eof_pos || desired_pos < 0) { // Seek outside bounds of file. // Failure should leave position unchanged. rep->seek (orig_pos, SEEK_SET); status = -1; } } else { // Seeking to the desired position failed. // Move back to original position and return failure status. rep->seek (orig_pos, SEEK_SET); status = -1; } } } return status; } int octave_stream::seek (const octave_value& tc_offset, const octave_value& tc_origin) { int retval = -1; // FIXME: should we have octave_value methods that handle off_t explicitly? octave_int64 val = tc_offset.xint64_scalar_value ("fseek: invalid value for offset"); off_t xoffset = val.value (); int conv_err = 0; int origin = SEEK_SET; if (tc_origin.is_string ()) { std::string xorigin = tc_origin.string_value ("fseek: invalid value for origin"); if (xorigin == "bof") origin = SEEK_SET; else if (xorigin == "cof") origin = SEEK_CUR; else if (xorigin == "eof") origin = SEEK_END; else conv_err = -1; } else { int xorigin = convert_to_valid_int (tc_origin, conv_err); if (! conv_err) { if (xorigin == -1) origin = SEEK_SET; else if (xorigin == 0) origin = SEEK_CUR; else if (xorigin == 1) origin = SEEK_END; else conv_err = -1; } } if (conv_err) ::error ("fseek: invalid value for origin"); retval = seek (xoffset, origin); if (retval != 0) // Note: error is member fcn from octave_stream, not ::error. error ("fseek: failed to seek to requested position"); return retval; } off_t octave_stream::tell (void) { off_t retval = -1; if (stream_ok ()) retval = rep->tell (); return retval; } int octave_stream::rewind (void) { return seek (0, SEEK_SET); } bool octave_stream::is_open (void) const { bool retval = false; if (stream_ok ()) retval = rep->is_open (); return retval; } void octave_stream::close (void) { if (stream_ok ()) rep->close (); } // FIXME: maybe these should be defined in lo-ieee.h? template <typename T> static inline bool is_old_NA (T) { return false; } template <> inline bool is_old_NA<double> (double val) { return __lo_ieee_is_old_NA (val); } template <typename T> static inline T replace_old_NA (T val) { return val; } template <> inline double replace_old_NA<double> (double val) { return __lo_ieee_replace_old_NA (val); } template <typename SRC_T, typename DST_T> static octave_value convert_and_copy (std::list<void *>& input_buf_list, octave_idx_type input_buf_elts, octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc, bool swap, bool do_float_fmt_conv, bool do_NA_conv, octave::mach_info::float_format from_flt_fmt) { typedef typename DST_T::element_type dst_elt_type; DST_T conv (dim_vector (nr, nc)); dst_elt_type *conv_data = conv.fortran_vec (); octave_idx_type j = 0; for (std::list<void *>::const_iterator it = input_buf_list.begin (); it != input_buf_list.end (); it++) { SRC_T *data = static_cast<SRC_T *> (*it); if (swap || do_float_fmt_conv) { if (do_NA_conv) { for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; i++, j++) { if (swap) swap_bytes<sizeof (SRC_T)> (&data[i]); else if (do_float_fmt_conv) do_float_format_conversion (&data[i], sizeof (SRC_T), 1, from_flt_fmt, octave::mach_info::native_float_format ()); dst_elt_type tmp (data[i]); if (is_old_NA (tmp)) tmp = replace_old_NA (tmp); conv_data[j] = tmp; } } else { for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; i++, j++) { if (swap) swap_bytes<sizeof (SRC_T)> (&data[i]); else if (do_float_fmt_conv) do_float_format_conversion (&data[i], sizeof (SRC_T), 1, from_flt_fmt, octave::mach_info::native_float_format ()); conv_data[j] = data[i]; } } } else { if (do_NA_conv) { for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; i++, j++) { dst_elt_type tmp (data[i]); if (is_old_NA (tmp)) tmp = replace_old_NA (tmp); conv_data[j] = tmp; } } else { for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; i++, j++) conv_data[j] = data[i]; } } delete [] data; } input_buf_list.clear (); for (octave_idx_type i = elts_read; i < nr * nc; i++) conv_data[i] = dst_elt_type (0); return conv; } typedef octave_value (*conv_fptr) (std::list<void *>& input_buf_list, octave_idx_type input_buf_elts, octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc, bool swap, bool do_float_fmt_conv, bool do_NA_conv, octave::mach_info::float_format from_flt_fmt); #define TABLE_ELT(T, U, V, W) \ conv_fptr_table[oct_data_conv::T][oct_data_conv::U] = convert_and_copy<V, W> #define FILL_TABLE_ROW(T, V) \ TABLE_ELT (T, dt_int8, V, int8NDArray); \ TABLE_ELT (T, dt_uint8, V, uint8NDArray); \ TABLE_ELT (T, dt_int16, V, int16NDArray); \ TABLE_ELT (T, dt_uint16, V, uint16NDArray); \ TABLE_ELT (T, dt_int32, V, int32NDArray); \ TABLE_ELT (T, dt_uint32, V, uint32NDArray); \ TABLE_ELT (T, dt_int64, V, int64NDArray); \ TABLE_ELT (T, dt_uint64, V, uint64NDArray); \ TABLE_ELT (T, dt_single, V, FloatNDArray); \ TABLE_ELT (T, dt_double, V, NDArray); \ TABLE_ELT (T, dt_char, V, charNDArray); \ TABLE_ELT (T, dt_schar, V, charNDArray); \ TABLE_ELT (T, dt_uchar, V, charNDArray); \ TABLE_ELT (T, dt_logical, V, boolNDArray); octave_value octave_stream::finalize_read (std::list<void *>& input_buf_list, octave_idx_type input_buf_elts, octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc, oct_data_conv::data_type input_type, oct_data_conv::data_type output_type, octave::mach_info::float_format ffmt) { octave_value retval; static bool initialized = false; // Table function pointers for return types x read types. static conv_fptr conv_fptr_table[oct_data_conv::dt_unknown][14]; if (! initialized) { for (int i = 0; i < oct_data_conv::dt_unknown; i++) for (int j = 0; j < 14; j++) conv_fptr_table[i][j] = 0; FILL_TABLE_ROW (dt_int8, int8_t); FILL_TABLE_ROW (dt_uint8, uint8_t); FILL_TABLE_ROW (dt_int16, int16_t); FILL_TABLE_ROW (dt_uint16, uint16_t); FILL_TABLE_ROW (dt_int32, int32_t); FILL_TABLE_ROW (dt_uint32, uint32_t); FILL_TABLE_ROW (dt_int64, int64_t); FILL_TABLE_ROW (dt_uint64, uint64_t); FILL_TABLE_ROW (dt_single, float); FILL_TABLE_ROW (dt_double, double); FILL_TABLE_ROW (dt_char, char); FILL_TABLE_ROW (dt_schar, signed char); FILL_TABLE_ROW (dt_uchar, unsigned char); FILL_TABLE_ROW (dt_logical, bool); initialized = true; } bool swap = false; if (ffmt == octave::mach_info::flt_fmt_unknown) ffmt = float_format (); if (octave::mach_info::words_big_endian ()) swap = (ffmt == octave::mach_info::flt_fmt_ieee_little_endian); else swap = (ffmt == octave::mach_info::flt_fmt_ieee_big_endian); bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double || input_type == oct_data_conv::dt_single) && ffmt != float_format ()); bool do_NA_conv = (output_type == oct_data_conv::dt_double); switch (output_type) { case oct_data_conv::dt_int8: case oct_data_conv::dt_uint8: case oct_data_conv::dt_int16: case oct_data_conv::dt_uint16: case oct_data_conv::dt_int32: case oct_data_conv::dt_uint32: case oct_data_conv::dt_int64: case oct_data_conv::dt_uint64: case oct_data_conv::dt_single: case oct_data_conv::dt_double: case oct_data_conv::dt_char: case oct_data_conv::dt_schar: case oct_data_conv::dt_uchar: case oct_data_conv::dt_logical: { conv_fptr fptr = conv_fptr_table[input_type][output_type]; retval = fptr (input_buf_list, input_buf_elts, elts_read, nr, nc, swap, do_float_fmt_conv, do_NA_conv, ffmt); } break; default: ::error ("read: invalid type specification"); } return retval; } octave_value octave_stream::read (const Array<double>& size, octave_idx_type block_size, oct_data_conv::data_type input_type, oct_data_conv::data_type output_type, octave_idx_type skip, octave::mach_info::float_format ffmt, octave_idx_type& count) { octave_value retval; octave_idx_type nr = -1; octave_idx_type nc = -1; bool one_elt_size_spec = false; if (! stream_ok ()) return retval; // FIXME: we may eventually want to make this extensible. // FIXME: we need a better way to ensure that this // numbering stays consistent with the order of the elements in the // data_type enum in the oct_data_conv class. // Expose this in a future version? octave_idx_type char_count = 0; count = 0; try { get_size (size, nr, nc, one_elt_size_spec, "fread"); } catch (const octave::execution_exception&) { invalid_operation ("fread", "reading"); } octave_idx_type elts_to_read; if (one_elt_size_spec) { // If NR == 0, Matlab returns [](0x0). // If NR > 0, the result will be a column vector with the given // number of rows. // If NR < 0, then we have Inf and the result will be a column // vector but we have to wait to see how big NR will be. if (nr == 0) nr = nc = 0; else nc = 1; } else { // Matlab returns [] even if there are two elements in the size // specification and one is nonzero. // If NC < 0 we have [NR, Inf] and we'll wait to decide how big NC // should be. if (nr == 0 || nc == 0) nr = nc = 0; } // FIXME: Ensure that this does not overflow. // Maybe try comparing nr * nc computed in double with // std::numeric_limits<octave_idx_type>::max (); elts_to_read = nr * nc; bool read_to_eof = elts_to_read < 0; octave_idx_type input_buf_elts = -1; if (skip == 0) { if (read_to_eof) input_buf_elts = 1024 * 1024; else input_buf_elts = elts_to_read; } else input_buf_elts = block_size; octave_idx_type input_elt_size = oct_data_conv::data_type_size (input_type); octave_idx_type input_buf_size = input_buf_elts * input_elt_size; assert (input_buf_size >= 0); // Must also work and return correct type object // for 0 elements to read. std::istream *isp = input_stream (); if (! isp) error ("fread: invalid input stream"); else { std::istream& is = *isp; std::list <void *> input_buf_list; while (is && ! is.eof () && (read_to_eof || count < elts_to_read)) { if (! read_to_eof) { octave_idx_type remaining_elts = elts_to_read - count; if (remaining_elts < input_buf_elts) input_buf_size = remaining_elts * input_elt_size; } char *input_buf = new char [input_buf_size]; is.read (input_buf, input_buf_size); size_t gcount = is.gcount (); char_count += gcount; octave_idx_type nel = gcount / input_elt_size; count += nel; input_buf_list.push_back (input_buf); if (is && skip != 0 && nel == block_size) { // Seek to skip. // If skip would move past EOF, position at EOF. off_t orig_pos = tell (); seek (0, SEEK_END); off_t eof_pos = tell (); // Is it possible for this to fail to return us to // the original position? seek (orig_pos, SEEK_SET); off_t remaining = eof_pos - orig_pos; if (remaining < skip) seek (0, SEEK_END); else seek (skip, SEEK_CUR); if (! is) break; } } if (read_to_eof) { if (nc < 0) { nc = count / nr; if (count % nr != 0) nc++; } else nr = count; } else if (count == 0) { nr = 0; nc = 0; } else if (count != nr * nc) { if (count % nr != 0) nc = count / nr + 1; else nc = count / nr; if (count < nr) nr = count; } retval = finalize_read (input_buf_list, input_buf_elts, count, nr, nc, input_type, output_type, ffmt); } return retval; } octave_idx_type octave_stream::write (const octave_value& data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, octave::mach_info::float_format flt_fmt) { octave_idx_type retval = -1; if (! stream_ok ()) invalid_operation ("fwrite", "writing"); else { if (flt_fmt == octave::mach_info::flt_fmt_unknown) flt_fmt = float_format (); octave_idx_type status = data.write (*this, block_size, output_type, skip, flt_fmt); if (status < 0) error ("fwrite: write error"); else retval = status; } return retval; } template <typename T, typename V> static void convert_chars (const void *data, void *conv_data, octave_idx_type n_elts) { const T *tt_data = static_cast<const T *> (data); V *vt_data = static_cast<V *> (conv_data); for (octave_idx_type i = 0; i < n_elts; i++) vt_data[i] = tt_data[i]; } template <typename T, typename V> static void convert_ints (const T *data, void *conv_data, octave_idx_type n_elts, bool swap) { typedef typename V::val_type val_type; val_type *vt_data = static_cast<val_type *> (conv_data); for (octave_idx_type i = 0; i < n_elts; i++) { // Yes, we want saturation semantics when converting to an integer type. V val (data[i]); vt_data[i] = val.value (); if (swap) swap_bytes<sizeof (val_type)> (&vt_data[i]); } } template <typename T> class ultimate_element_type { public: typedef T type; }; template <typename T> class ultimate_element_type<octave_int<T> > { public: typedef T type; }; template <typename T> static bool convert_data (const T *data, void *conv_data, octave_idx_type n_elts, oct_data_conv::data_type output_type, octave::mach_info::float_format flt_fmt) { bool retval = true; bool swap = false; if (octave::mach_info::words_big_endian ()) swap = (flt_fmt == octave::mach_info::flt_fmt_ieee_little_endian); else swap = (flt_fmt == octave::mach_info::flt_fmt_ieee_big_endian); bool do_float_conversion = flt_fmt != octave::mach_info::float_format (); typedef typename ultimate_element_type<T>::type ult_elt_type; switch (output_type) { case oct_data_conv::dt_char: convert_chars<ult_elt_type, char> (data, conv_data, n_elts); break; case oct_data_conv::dt_schar: convert_chars<ult_elt_type, signed char> (data, conv_data, n_elts); break; case oct_data_conv::dt_uchar: convert_chars<ult_elt_type, unsigned char> (data, conv_data, n_elts); break; case oct_data_conv::dt_int8: convert_ints<T, octave_int8> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint8: convert_ints<T, octave_uint8> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int16: convert_ints<T, octave_int16> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint16: convert_ints<T, octave_uint16> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int32: convert_ints<T, octave_int32> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint32: convert_ints<T, octave_uint32> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int64: convert_ints<T, octave_int64> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint64: convert_ints<T, octave_uint64> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_single: { float *vt_data = static_cast<float *> (conv_data); for (octave_idx_type i = 0; i < n_elts; i++) { vt_data[i] = data[i]; if (do_float_conversion) do_float_format_conversion (&vt_data[i], 1, flt_fmt); } } break; case oct_data_conv::dt_double: { double *vt_data = static_cast<double *> (conv_data); for (octave_idx_type i = 0; i < n_elts; i++) { vt_data[i] = data[i]; if (do_float_conversion) do_double_format_conversion (&vt_data[i], 1, flt_fmt); } } break; default: ::error ("write: invalid type specification"); } return retval; } bool octave_stream::write_bytes (const void *data, size_t nbytes) { bool status = false; std::ostream *osp = output_stream (); if (osp) { std::ostream& os = *osp; if (os) { os.write (static_cast<const char *> (data), nbytes); if (os) status = true; } } return status; } bool octave_stream::skip_bytes (size_t skip) { bool status = false; std::ostream *osp = output_stream (); if (! osp) return false; std::ostream& os = *osp; // Seek to skip when inside bounds of existing file. // Otherwise, write NUL to skip. off_t orig_pos = tell (); seek (0, SEEK_END); off_t eof_pos = tell (); // Is it possible for this to fail to return us to the original position? seek (orig_pos, SEEK_SET); size_t remaining = eof_pos - orig_pos; if (remaining < skip) { seek (0, SEEK_END); // FIXME: probably should try to write larger blocks... unsigned char zero = 0; for (size_t j = 0; j < skip - remaining; j++) os.write (reinterpret_cast<const char *> (&zero), 1); } else seek (skip, SEEK_CUR); if (os) status = true; return status; } template <typename T> octave_idx_type octave_stream::write (const Array<T>& data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, octave::mach_info::float_format flt_fmt) { bool swap = false; if (octave::mach_info::words_big_endian ()) swap = (flt_fmt == octave::mach_info::flt_fmt_ieee_little_endian); else swap = (flt_fmt == octave::mach_info::flt_fmt_ieee_big_endian); bool do_data_conversion = (swap || ! is_equivalent_type<T> (output_type) || flt_fmt != octave::mach_info::float_format ()); octave_idx_type nel = data.numel (); octave_idx_type chunk_size; if (skip != 0) chunk_size = block_size; else if (do_data_conversion) chunk_size = 1024 * 1024; else chunk_size = nel; octave_idx_type i = 0; const T *pdata = data.data (); while (i < nel) { if (skip != 0) { if (! skip_bytes (skip)) return -1; } octave_idx_type remaining_nel = nel - i; if (chunk_size > remaining_nel) chunk_size = remaining_nel; bool status = false; if (do_data_conversion) { size_t output_size = chunk_size * oct_data_conv::data_type_size (output_type); OCTAVE_LOCAL_BUFFER (unsigned char, conv_data, output_size); status = convert_data (&pdata[i], conv_data, chunk_size, output_type, flt_fmt); if (status) status = write_bytes (conv_data, output_size); } else status = write_bytes (pdata, sizeof (T) * chunk_size); if (! status) return -1; i += chunk_size; } return nel; } #define INSTANTIATE_WRITE(T) \ template \ octave_idx_type \ octave_stream::write (const Array<T>& data, octave_idx_type block_size, \ oct_data_conv::data_type output_type, \ octave_idx_type skip, \ octave::mach_info::float_format flt_fmt) INSTANTIATE_WRITE (octave_int8); INSTANTIATE_WRITE (octave_uint8); INSTANTIATE_WRITE (octave_int16); INSTANTIATE_WRITE (octave_uint16); INSTANTIATE_WRITE (octave_int32); INSTANTIATE_WRITE (octave_uint32); INSTANTIATE_WRITE (octave_int64); INSTANTIATE_WRITE (octave_uint64); INSTANTIATE_WRITE (int8_t); INSTANTIATE_WRITE (uint8_t); INSTANTIATE_WRITE (int16_t); INSTANTIATE_WRITE (uint16_t); INSTANTIATE_WRITE (int32_t); INSTANTIATE_WRITE (uint32_t); INSTANTIATE_WRITE (int64_t); INSTANTIATE_WRITE (uint64_t); INSTANTIATE_WRITE (bool); #if defined (OCTAVE_HAVE_OVERLOAD_CHAR_INT8_TYPES) INSTANTIATE_WRITE (char); #endif INSTANTIATE_WRITE (float); INSTANTIATE_WRITE (double); octave_value octave_stream::scanf (const std::string& fmt, const Array<double>& size, octave_idx_type& count, const std::string& who) { octave_value retval; if (stream_ok ()) retval = rep->scanf (fmt, size, count, who); return retval; } octave_value octave_stream::scanf (const octave_value& fmt, const Array<double>& size, octave_idx_type& count, const std::string& who) { octave_value retval = Matrix (); if (fmt.is_string ()) { std::string sfmt = fmt.string_value (); if (fmt.is_sq_string ()) sfmt = do_string_escapes (sfmt); retval = scanf (sfmt, size, count, who); } else { // Note: error is member fcn from octave_stream, not ::error. error (who + ": format must be a string"); } return retval; } octave_value_list octave_stream::oscanf (const std::string& fmt, const std::string& who) { octave_value_list retval; if (stream_ok ()) retval = rep->oscanf (fmt, who); return retval; } octave_value_list octave_stream::oscanf (const octave_value& fmt, const std::string& who) { octave_value_list retval; if (fmt.is_string ()) { std::string sfmt = fmt.string_value (); if (fmt.is_sq_string ()) sfmt = do_string_escapes (sfmt); retval = oscanf (sfmt, who); } else { // Note: error is member fcn from octave_stream, not ::error. error (who + ": format must be a string"); } return retval; } octave_value octave_stream::textscan (const std::string& fmt, octave_idx_type ntimes, const octave_value_list& options, const std::string& who, octave_idx_type& count) { return (stream_ok () ? rep->do_textscan (fmt, ntimes, options, who, count) : octave_value ()); } int octave_stream::printf (const std::string& fmt, const octave_value_list& args, const std::string& who) { int retval = -1; if (stream_ok ()) retval = rep->printf (fmt, args, who); return retval; } int octave_stream::printf (const octave_value& fmt, const octave_value_list& args, const std::string& who) { int retval = 0; if (fmt.is_string ()) { std::string sfmt = fmt.string_value (); if (fmt.is_sq_string ()) sfmt = do_string_escapes (sfmt); retval = printf (sfmt, args, who); } else { // Note: error is member fcn from octave_stream, not ::error. error (who + ": format must be a string"); } return retval; } int octave_stream::puts (const std::string& s, const std::string& who) { int retval = -1; if (stream_ok ()) retval = rep->puts (s, who); return retval; } // FIXME: maybe this should work for string arrays too. int octave_stream::puts (const octave_value& tc_s, const std::string& who) { int retval = -1; if (tc_s.is_string ()) { std::string s = tc_s.string_value (); retval = puts (s, who); } else { // Note: error is member fcn from octave_stream, not ::error. error (who + ": argument must be a string"); } return retval; } bool octave_stream::eof (void) const { int retval = -1; if (stream_ok ()) retval = rep->eof (); return retval; } std::string octave_stream::error (bool clear, int& err_num) { std::string retval = "invalid stream object"; if (stream_ok (false)) retval = rep->error (clear, err_num); return retval; } std::string octave_stream::name (void) const { std::string retval; if (stream_ok ()) retval = rep->name (); return retval; } int octave_stream::mode (void) const { int retval = 0; if (stream_ok ()) retval = rep->mode (); return retval; } octave::mach_info::float_format octave_stream::float_format (void) const { octave::mach_info::float_format retval = octave::mach_info::flt_fmt_unknown; if (stream_ok ()) retval = rep->float_format (); return retval; } std::string octave_stream::mode_as_string (int mode) { std::string retval = "???"; std::ios::openmode in_mode = static_cast<std::ios::openmode> (mode); if (in_mode == std::ios::in) retval = "r"; else if (in_mode == std::ios::out || in_mode == (std::ios::out | std::ios::trunc)) retval = "w"; else if (in_mode == (std::ios::out | std::ios::app)) retval = "a"; else if (in_mode == (std::ios::in | std::ios::out)) retval = "r+"; else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc)) retval = "w+"; else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate)) retval = "a+"; else if (in_mode == (std::ios::in | std::ios::binary)) retval = "rb"; else if (in_mode == (std::ios::out | std::ios::binary) || in_mode == (std::ios::out | std::ios::trunc | std::ios::binary)) retval = "wb"; else if (in_mode == (std::ios::out | std::ios::app | std::ios::binary)) retval = "ab"; else if (in_mode == (std::ios::in | std::ios::out | std::ios::binary)) retval = "r+b"; else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)) retval = "w+b"; else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate | std::ios::binary)) retval = "a+b"; return retval; } octave_stream_list *octave_stream_list::instance = 0; bool octave_stream_list::instance_ok (void) { bool retval = true; if (! instance) { instance = new octave_stream_list (); if (instance) singleton_cleanup_list::add (cleanup_instance); } if (! instance) ::error ("unable to create stream list object!"); return retval; } int octave_stream_list::insert (octave_stream& os) { return (instance_ok ()) ? instance->do_insert (os) : -1; } octave_stream octave_stream_list::lookup (int fid, const std::string& who) { return (instance_ok ()) ? instance->do_lookup (fid, who) : octave_stream (); } octave_stream octave_stream_list::lookup (const octave_value& fid, const std::string& who) { return (instance_ok ()) ? instance->do_lookup (fid, who) : octave_stream (); } int octave_stream_list::remove (int fid, const std::string& who) { return (instance_ok ()) ? instance->do_remove (fid, who) : -1; } int octave_stream_list::remove (const octave_value& fid, const std::string& who) { return (instance_ok ()) ? instance->do_remove (fid, who) : -1; } void octave_stream_list::clear (bool flush) { if (instance) instance->do_clear (flush); } string_vector octave_stream_list::get_info (int fid) { return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); } string_vector octave_stream_list::get_info (const octave_value& fid) { return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); } std::string octave_stream_list::list_open_files (void) { return (instance_ok ()) ? instance->do_list_open_files () : ""; } octave_value octave_stream_list::open_file_numbers (void) { return (instance_ok ()) ? instance->do_open_file_numbers () : octave_value (); } int octave_stream_list::get_file_number (const octave_value& fid) { return (instance_ok ()) ? instance->do_get_file_number (fid) : -1; } int octave_stream_list::do_insert (octave_stream& os) { // Insert item with key corresponding to file-descriptor. int stream_number = os.file_number (); if (stream_number == -1) return stream_number; // Should we test for // // (list.find (stream_number) != list.end () // && list[stream_number].is_open ()) // // and respond with "error ("internal error: ...")"? It should not // happen except for some bug or if the user has opened a stream with // an interpreted command, but closed it directly with a system call // in an oct-file; then the kernel knows the fd is free, but Octave // does not know. If it happens, it should not do harm here to simply // overwrite this entry, although the wrong entry might have done harm // before. if (list.size () >= list.max_size ()) ::error ("could not create file id"); list[stream_number] = os; return stream_number; } OCTAVE_NORETURN static void err_invalid_file_id (int fid, const std::string& who) { if (who.empty ()) ::error ("invalid stream number = %d", fid); else ::error ("%s: invalid stream number = %d", who.c_str (), fid); } octave_stream octave_stream_list::do_lookup (int fid, const std::string& who) const { octave_stream retval; if (fid < 0) err_invalid_file_id (fid, who); if (lookup_cache != list.end () && lookup_cache->first == fid) retval = lookup_cache->second; else { ostrl_map::const_iterator iter = list.find (fid); if (iter == list.end ()) err_invalid_file_id (fid, who); retval = iter->second; lookup_cache = iter; } return retval; } octave_stream octave_stream_list::do_lookup (const octave_value& fid, const std::string& who) const { int i = get_file_number (fid); return do_lookup (i, who); } int octave_stream_list::do_remove (int fid, const std::string& who) { // Can't remove stdin (std::cin), stdout (std::cout), or stderr (std::cerr). if (fid < 3) err_invalid_file_id (fid, who); ostrl_map::iterator iter = list.find (fid); if (iter == list.end ()) err_invalid_file_id (fid, who); octave_stream os = iter->second; list.erase (iter); lookup_cache = list.end (); // FIXME: is this check redundant? if (! os.is_valid ()) err_invalid_file_id (fid, who); os.close (); return 0; } int octave_stream_list::do_remove (const octave_value& fid, const std::string& who) { int retval = -1; if (fid.is_string () && fid.string_value () == "all") { do_clear (false); retval = 0; } else { int i = get_file_number (fid); retval = do_remove (i, who); } return retval; } void octave_stream_list::do_clear (bool flush) { if (flush) { // Flush stdout and stderr. list[1].flush (); list[2].flush (); } for (ostrl_map::iterator iter = list.begin (); iter != list.end (); ) { int fid = iter->first; if (fid < 3) // Don't delete stdin, stdout, stderr { iter++; continue; } octave_stream os = iter->second; std::string name = os.name (); std::transform (name.begin (), name.end (), name.begin (), tolower); // FIXME: This test for gnuplot is hardly foolproof. if (name.find ("gnuplot") != std::string::npos) { // Don't close down pipes to gnuplot iter++; continue; } // Normal file handle. Close and delete from list. if (os.is_valid ()) os.close (); list.erase (iter++); } lookup_cache = list.end (); } string_vector octave_stream_list::do_get_info (int fid) const { octave_stream os = do_lookup (fid); if (! os.is_valid ()) ::error ("invalid file id = %d", fid); string_vector retval (3); retval(0) = os.name (); retval(1) = octave_stream::mode_as_string (os.mode ()); retval(2) = octave::mach_info::float_format_as_string (os.float_format ()); return retval; } string_vector octave_stream_list::do_get_info (const octave_value& fid) const { int conv_err = 0; int int_fid = convert_to_valid_int (fid, conv_err); if (conv_err) ::error ("file id must be a file object or integer value"); return do_get_info (int_fid); } std::string octave_stream_list::do_list_open_files (void) const { std::ostringstream buf; buf << "\n" << " number mode arch name\n" << " ------ ---- ---- ----\n"; for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++) { octave_stream os = p->second; buf << " " << std::setiosflags (std::ios::right) << std::setw (4) << p->first << " " // reset necessary in addition to setiosflags since this is one stmt. << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left) << std::setw (3) << octave_stream::mode_as_string (os.mode ()) << " " << std::setw (9) << octave::mach_info::float_format_as_string (os.float_format ()) << " " << os.name () << "\n"; } buf << "\n"; return buf.str (); } octave_value octave_stream_list::do_open_file_numbers (void) const { Matrix retval (1, list.size (), 0.0); int num_open = 0; for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++) { // Skip stdin, stdout, and stderr. if (p->first > 2 && p->second) retval(0,num_open++) = p->first; } retval.resize ((num_open > 0), num_open); return retval; } int octave_stream_list::do_get_file_number (const octave_value& fid) const { int retval = -1; if (fid.is_string ()) { std::string nm = fid.string_value (); for (ostrl_map::const_iterator p = list.begin (); p != list.end (); p++) { // stdin, stdout, and stderr are unnamed. if (p->first > 2) { octave_stream os = p->second; if (os && os.name () == nm) { retval = p->first; break; } } } } else { int conv_err = 0; int int_fid = convert_to_valid_int (fid, conv_err); if (conv_err) ::error ("file id must be a file object, std::string, or integer value"); retval = int_fid; } return retval; }