functionend ignored
David Grundberg
individ at acc.umu.se
Mon Jul 13 06:23:01 CDT 2009
Hi,
been working on lint, but I got stuck on this behavior I don't agree with.
Bug report for Octave 3.1.55 configured for i686-pc-linux-gnu
hg tip:
changeset: 9431:bfc7b000a229
tag: tip
user: John W. Eaton <jwe at octave.org>
date: Sat Jul 11 12:46:10 2009 -0400
summary: file-ops.cc (file_ops::symlink, file_ops::readlink): avoid
incorrectly sized buffer
Description:
-----------
* A user function may end with any number of 'functionend's, and no
error will be given.
Repeat-By:
---------
1. Create a file buggy.m:
cat > buggy.m << EOF
function [] = buggy()
endfunction
endfunction
EOF
2. Run octave like
/opt/octave-head/bin/octave --eval 'addpath("."); __display_tokens__(1);
buggy'
3. Expected behavior is a syntax error. But the experienced behavior
is that the function runs as normal.
Note that running
/opt/octave-head/bin/octave --eval '__display_tokens__(1);' buggy.m
does raise a syntax error because of the extra endfunction.
Comments:
--------
* Ends seems to be ignored? In the following excerpts, note that the
end token is replaced with a '\n' in the first run.
Running as a function from the Octave prompt:
octave:1> buggy
NAME
\n
FCN
[
]
'='
NAME
(
)
\n
\n
\n
END_OF_INPUT
parsed function end as end of input!
END_OF_INPUT
octave:2>
Running buggy.m as an argument to octave:
FCN
[
]
'='
NAME
(
)
\n
END
parsed function end as a end token!
\n
END
parse error near line 3 of file buggy.m
syntax error
>>> endfunction
For completeness, here are the changes I have done to the tip:
********************************************************************************
diff -r bfc7b000a229 src/parse.y
--- a/src/parse.y Sat Jul 11 12:46:10 2009 -0400
+++ b/src/parse.y Mon Jul 13 12:16:03 2009 +0200
@@ -268,7 +268,7 @@
// Create a no-op statement for end_function.
static tree_statement *
-make_end (const std::string& type, int l, int c);
+make_end (const std::string& type, int l, int c, bool implicit_end =
false);
// Do most of the work for defining a function.
static octave_user_function *
@@ -1281,6 +1281,7 @@
function_end : END
{
+ std::cout << "parsed function end as a end token!" <<
std::endl;
if (end_token_ok ($1, token::function_end))
$$ = make_end ("endfunction", $1->line (), $1->column ());
else
@@ -1288,13 +1289,14 @@
}
| END_OF_INPUT
{
+ std::cout << "parsed function end as end of input!" <<
std::endl;
if (lexer_flags.parsing_nested_function)
lexer_flags.parsing_nested_function = -1;
if (reading_fcn_file || reading_script_file
|| get_input_from_eval_string)
$$ = make_end ("endfunction", input_line_number,
- current_input_column);
+ current_input_column, true);
else
YYABORT;
}
@@ -2562,9 +2564,9 @@
}
static tree_statement *
-make_end (const std::string& type, int l, int c)
-{
- return make_statement (new tree_no_op_command (type, l, c));
+make_end (const std::string& type, int l, int c, bool implicit_end)
+{
+ return make_statement (new tree_no_op_command (type, l, c,
implicit_end));
}
// Do most of the work for defining a function.
diff -r bfc7b000a229 src/pt-cmd.h
--- a/src/pt-cmd.h Sat Jul 11 12:46:10 2009 -0400
+++ b/src/pt-cmd.h Mon Jul 13 12:16:03 2009 +0200
@@ -64,9 +64,15 @@
{
public:
- tree_no_op_command (const std::string& cmd = "no_op", int l = -1, int
c = -1)
- : tree_command (l, c), eof (cmd == "endfunction" || cmd ==
"endscript"),
- orig_cmd (cmd) { }
+ tree_no_op_command (const std::string& cmd = "no_op",
+ int l = -1,
+ int c = -1,
+ bool end_implicit = false)
+ : tree_command (l, c),
+ end_of_fcn_or_script (cmd == "endfunction" || cmd == "endscript"),
+ implicit_end (end_implicit),
+ orig_cmd (cmd)
+ { }
~tree_no_op_command (void) { }
@@ -75,13 +81,20 @@
void accept (tree_walker& tw);
- bool is_end_of_fcn_or_script (void) const { return eof; }
+ bool is_end_of_fcn_or_script (void) const { return
end_of_fcn_or_script; }
+
+ bool is_implicit_end (void) const { return implicit_end; }
std::string original_command (void) { return orig_cmd; }
private:
- bool eof;
+ bool end_of_fcn_or_script;
+
+ // User function ended with EOF instead of an explicit functionend.
+ // Implies end_of_fcn_or_script.
+
+ bool implicit_end;
std::string orig_cmd;
diff -r bfc7b000a229 src/pt-pr-code.cc
--- a/src/pt-pr-code.cc Sat Jul 11 12:46:10 2009 -0400
+++ b/src/pt-pr-code.cc Mon Jul 13 12:16:03 2009 +0200
@@ -721,6 +721,9 @@
void
tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
{
+ if (cmd.is_implicit_end ())
+ return;
+
indent ();
os << cmd.original_command ();
*********************************************************************************
Configuration (please do not edit this section):
-----------------------------------------------
uname output: Linux lack 2.6.27-14-generic #1 SMP Wed Apr 15
18:59:16 UTC 2009 i686 GNU/Linux
configure opts: '--prefix' '/opt/octave-head' '-C' '--disable-static'
'--enable-shared' 'CXXFLAGS=-O0 -ggdb'
Fortran compiler: gfortran
FFLAGS: -O -mieee-fp
FLIBS: -L/usr/lib/gcc/i486-linux-gnu/4.3.2
-L/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib -L/lib/../lib
-L/usr/lib/../lib -L/usr/lib/gcc/i486-linux-gnu/4.3.2/../../.. -lhdf5
-lz -lgfortranbegin -lgfortran -lm
CPPFLAGS:
INCFLAGS: -I. -I/home/david/c/octave -I. -I./liboctave -I./src
-I./libcruft/misc -I/home/david/c/octave
-I/home/david/c/octave/liboctave -I/home/david/c/octave/src
-I/home/david/c/octave/libcruft/misc
C compiler: gcc, version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)
CFLAGS: -g -O2
CPICFLAG: -fPIC
C++ compiler: g++, version 4.3.2
CXXFLAGS: -O0 -ggdb
CXXPICFLAG: -fPIC
LD_CXX: g++
LDFLAGS:
LIBFLAGS: -L.
RLD_FLAG: -Wl,-rpath -Wl,/opt/octave-head/lib/octave-3.1.55
BLAS_LIBS: -llapack -lblas
FFTW_LIBS: -lfftw3 -lfftw3f
LIBS: -lreadline -lncurses -ldl -lblas -lhdf5 -lz -lm
LEXLIB:
LIBGLOB:
SED: /bin/sed
DEFS:
-DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION=""
-DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DOCTAVE_SOURCE=1
-D_GNU_SOURCE=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1
-DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -D__EXTENSIONS__=1
-D_POSIX_PTHREAD_SEMANTICS=1 -D_TANDEM_SOURCE=1 -DSEPCHAR=':'
-DSEPCHAR_STR=":" -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1
-DCXX_ISO_COMPLIANT_LIBRARY=1 -DHAVE_X_WINDOWS=1 -DHAVE_LIBM=1
-DHAVE_PCRE_COMPILE=1 -DHAVE_PCRE=1 -DHAVE_REGEXEC=1 -DHAVE_REGEX=1
-DHAVE_ZLIB_H=1 -DHAVE_ZLIB=1 -DHAVE_HDF5_H=1 -DHAVE_HDF5=1
-DHAVE_H5GGET_NUM_OBJS=1 -DHAVE_FFTW3=1 -DHAVE_GL_GL_H=1
-DHAVE_GL_GLU_H=1 -DHAVE_FONTCONFIG=1 -DHAVE_IEEE754_DATA_FORMAT=1
-DF77_FUNC(name,NAME)=name ## _ -DF77_FUNC_(name,NAME)=name ## _
-DHAVE_BLAS=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETPWNAM=1 -DHAVE_DEV_T=1
-DHAVE_INO_T=1 -DHAVE_NLINK_T=1 -DHAVE_NLINK_T=1 -DHAVE_LONG_LONG_INT=1
-DHAVE_UNSIGNED_LONG_LONG_INT=1 -DHAVE_SIGSET_T=1 -DHAVE_SIG_ATOMIC_T=1
-DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8
-DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_PLACEMENT_DELETE=1
-DHAVE_DYNAMIC_AUTO_ARRAYS=1 -DHAVE_FAST_INT_OPS=1
-DSIZEOF_LONG_DOUBLE=12 -DSTDC_HEADERS=1 -DHAVE_DIRENT_H=1
-DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_ASSERT_H=1
-DHAVE_CURSES_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1 -DHAVE_FLOAT_H=1
-DHAVE_GRP_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1
-DHAVE_MEMORY_H=1 -DHAVE_NCURSES_H=1 -DHAVE_POLL_H=1 -DHAVE_PTHREAD_H=1
-DHAVE_PWD_H=1 -DHAVE_STDINT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1
-DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_POLL_H=1
-DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_STAT_H=1
-DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_TYPES_H=1
-DHAVE_SYS_UTSNAME_H=1 -DHAVE_TERMCAP_H=1 -DHAVE_UNISTD_H=1
-DHAVE_UTIME_H=1 -DHAVE_SSTREAM=1 -DHAVE_TERMIOS_H=1 -DHAVE_TERMIO_H=1
-DHAVE_SGTTY_H=1 -DHAVE_GLOB_H=1 -DHAVE_FNMATCH_H=1 -DHAVE_FNMATCH=1
-DHAVE_GLOB=1 -DHAVE_ATEXIT=1 -DHAVE_BASENAME=1 -DHAVE_BCOPY=1
-DHAVE_BZERO=1 -DHAVE_CANONICALIZE_FILE_NAME=1 -DHAVE_CHMOD=1
-DHAVE_DUP2=1 -DHAVE_ENDGRENT=1 -DHAVE_ENDPWENT=1 -DHAVE_EXECVP=1
-DHAVE_EXPM1=1 -DHAVE_EXPM1F=1 -DHAVE_FCNTL=1 -DHAVE_FORK=1
-DHAVE_FSTAT=1 -DHAVE_GETCWD=1 -DHAVE_GETEGID=1 -DHAVE_GETEUID=1
-DHAVE_GETGID=1 -DHAVE_GETGRENT=1 -DHAVE_GETGRGID=1 -DHAVE_GETGRNAM=1
-DHAVE_GETPGRP=1 -DHAVE_GETPID=1 -DHAVE_GETPPID=1 -DHAVE_GETPWENT=1
-DHAVE_GETPWUID=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_GETUID=1 -DHAVE_GETWD=1
-DHAVE_KILL=1 -DHAVE_LGAMMA=1 -DHAVE_LGAMMAF=1 -DHAVE_LGAMMA_R=1
-DHAVE_LGAMMAF_R=1 -DHAVE_LINK=1 -DHAVE_LOCALTIME_R=1 -DHAVE_LOG1P=1
-DHAVE_LOG1PF=1 -DHAVE_LSTAT=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1
-DHAVE_MKFIFO=1 -DHAVE_MKSTEMP=1 -DHAVE_ON_EXIT=1 -DHAVE_PIPE=1
-DHAVE_POLL=1 -DHAVE_PUTENV=1 -DHAVE_RAISE=1 -DHAVE_READLINK=1
-DHAVE_REALPATH=1 -DHAVE_RENAME=1 -DHAVE_RINDEX=1 -DHAVE_RMDIR=1
-DHAVE_ROUNDL=1 -DHAVE_SELECT=1 -DHAVE_SETGRENT=1 -DHAVE_SETLOCALE=1
-DHAVE_SETPWENT=1 -DHAVE_SETVBUF=1 -DHAVE_SIGACTION=1
-DHAVE_SIGLONGJMP=1 -DHAVE_SIGPENDING=1 -DHAVE_SIGPROCMASK=1
-DHAVE_SIGSUSPEND=1 -DHAVE_SNPRINTF=1 -DHAVE_STAT=1 -DHAVE_STRCASECMP=1
-DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRNCASECMP=1 -DHAVE_STRPTIME=1
-DHAVE_STRSIGNAL=1 -DHAVE_SYMLINK=1 -DHAVE_TEMPNAM=1 -DHAVE_TGAMMAF=1
-DHAVE_TRUNC=1 -DHAVE_UMASK=1 -DHAVE_UNAME=1 -DHAVE_UNLINK=1
-DHAVE_USLEEP=1 -DHAVE_UTIME=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
-DHAVE_VSNPRINTF=1 -DHAVE_WAITPID=1 -DHAVE_DECL_EXP2=1 -DHAVE_DECL_ROUND=1
-DHAVE_DECL_TGAMMA=1 -DHAVE_EXP2=1 -DHAVE_ROUND=1 -DHAVE_TGAMMA=1
-DHAVE_STRFTIME=1 -DHAVE_C99_VSNPRINTF=1 -DHAVE_LIBDL=1 -DHAVE_DLOPEN=1
-DHAVE_DLSYM=1 -DHAVE_DLERROR=1 -DHAVE_DLCLOSE=1 -DHAVE_DLOPEN_API=1
-DENABLE_DYNAMIC_LINKING=1 -DHAVE_TIMEVAL=1 -DHAVE_CMATH_ISNAN=1
-DHAVE_CMATH_ISNANF=1 -DHAVE_CMATH_ISINF=1 -DHAVE_CMATH_ISINFF=1
-DHAVE_CMATH_ISFINITE=1 -DHAVE_CMATH_ISFINITEF=1 -DHAVE_FINITE=1
-DHAVE_ISNAN=1 -DHAVE_ISINF=1 -DHAVE_COPYSIGN=1 -DHAVE_DECL_SIGNBIT=1
-DHAVE_ACOSH=1 -DHAVE_ACOSHF=1 -DHAVE_ASINH=1 -DHAVE_ASINHF=1
-DHAVE_ATANH=1 -DHAVE_ATANHF=1 -DHAVE_ERF=1 -DHAVE_ERFF=1 -DHAVE_ERFC=1
-DHAVE_ERFCF=1 -DHAVE_EXP2F=1 -DHAVE_LOG2=1 -DHAVE_LOG2F=1 -DHAVE_HYPOTF=1
-DHAVE_STRUCT_STAT_ST_BLKSIZE=1 -DHAVE_STRUCT_STAT_ST_BLOCKS=1
-DHAVE_STRUCT_STAT_ST_RDEV=1 -DHAVE_STRUCT_TM_TM_ZONE=1
-DHAVE_TM_ZONE=1 -DUSE_READLINE=1 -DEXCEPTION_IN_MATH=1 -DRETSIGTYPE=void
-DHAVE_DECL_SYS_SIGLIST=1 -DHAVE_POSIX_SIGNALS=1 -DRETSIGTYPE_IS_VOID=1
-DHAVE_GETRUSAGE=1 -DHAVE_TIMES=1 -DYYTEXT_POINTER=1
More information about the Bug-octave
mailing list