# HG changeset patch # User jwe # Date 1144352315 0 # Node ID 1c36a2e822664c0d0f8749dcee8df778907f9b94 # Parent a527e0f77aa5351370baaf78f391da76b11affb6 [project @ 2006-04-06 19:38:34 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,7 +1,10 @@ 2006-04-06 John W. Eaton - * parse.y (Fmfilename): If no function is on the call stack check - to see whether we are reading a script file. + * parse.y (parse_and_execute, parse_fcn_file): + Create octave_script_function object and push it on the call stack. + + * parse.y (Fmfilename): Check for script or user function file on + call stack. * ov-builtin.cc (octave_builtin::do_multi_index_op): Use octave_call_stack instead of curr_function to save pointer to @@ -34,12 +37,15 @@ * parse.y (Fmfilename): Likewise. Check for scripting language caller, not any calling function. -2006-04-05 John W. Eaton + * ov-usr-fcn.h (octave_user_script): New class. + * ov-fcn.h (octave_function::is_user_script): New virtual function. * toplev.h, toplev.cc (octave_call_stack): New class. * debug.cc (Fdbwhere): Use get_user_function here. +2006-04-05 John W. Eaton + * Makefile.in (mk-pkg-add): Use mfilename to simplify. (PKG_ADD): Don't pass --prefix arg to mk-pkg-add. (PKG_ADD.inst): Delete target. diff --git a/src/debug.cc b/src/debug.cc --- a/src/debug.cc +++ b/src/debug.cc @@ -59,7 +59,7 @@ octave_user_function *dbg_fcn = 0; if (fname == "") - dbg_fcn = octave_call_stack::caller_script (); + dbg_fcn = octave_call_stack::caller_user_function (); else { symbol_record *ptr = curr_sym_tab->lookup (fname); diff --git a/src/error.cc b/src/error.cc --- a/src/error.cc +++ b/src/error.cc @@ -378,7 +378,8 @@ int l = -1; int c = -1; - octave_user_function *fcn = octave_call_stack::caller_script (); + octave_function *fcn + = octave_call_stack::caller_user_script_or_function (); if (fcn) { @@ -545,7 +546,7 @@ if ((interactive || forced_interactive) && Vdebug_on_warning - && octave_call_stack::caller_script ()) + && octave_call_stack::caller_user_script_or_function ()) { unwind_protect_bool (Vdebug_on_warning); Vdebug_on_warning = false; @@ -584,7 +585,7 @@ if ((interactive || forced_interactive) && Vdebug_on_error && init_state == 0 - && octave_call_stack::caller_script ()) + && octave_call_stack::caller_user_script_or_function ()) { unwind_protect_bool (Vdebug_on_error); Vdebug_on_error = false; diff --git a/src/input.cc b/src/input.cc --- a/src/input.cc +++ b/src/input.cc @@ -547,7 +547,8 @@ if (debug) { - octave_user_function *caller = octave_call_stack::caller_script (); + octave_function *caller + = octave_call_stack::caller_user_script_or_function (); if (caller) { diff --git a/src/ov-fcn.h b/src/ov-fcn.h --- a/src/ov-fcn.h +++ b/src/ov-fcn.h @@ -70,6 +70,8 @@ virtual bool is_nested_function (void) const { return false; } + virtual bool is_user_script (void) const { return false; } + virtual bool is_user_function (void) const { return false; } virtual bool takes_varargs (void) const { return false; } diff --git a/src/ov-usr-fcn.cc b/src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -59,6 +59,12 @@ "user-defined function", "user-defined function"); +DEFINE_OCTAVE_ALLOCATOR (octave_user_script); + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_script, + "user-defined script", + "user-defined script"); + // Ugh. This really needs to be simplified (code/data? // extrinsic/intrinsic state?). @@ -746,7 +752,7 @@ if (nargin == 0) { - octave_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) { @@ -790,7 +796,7 @@ if (nargin == 0) { - octave_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) { @@ -836,7 +842,7 @@ if (nargin == 1) { - octave_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) { diff --git a/src/ov-usr-fcn.h b/src/ov-usr-fcn.h --- a/src/ov-usr-fcn.h +++ b/src/ov-usr-fcn.h @@ -44,7 +44,47 @@ class symbol_table; class symbol_record; -// Builtin functions. +// Scripts. + +class +octave_user_script : public octave_function +{ +public: + + octave_user_script (void) { } + + octave_user_script (const std::string& fnm, const std::string& nm, + const std::string& ds) + : octave_function (nm, ds), file_name (fnm) { } + + ~octave_user_script (void) { } + + // Scripts and user functions are both considered "scripts" because + // they are written in Octave's scripting language. + + bool is_user_script (void) const { return true; } + + void stash_fcn_file_name (const std::string& nm) { file_name = nm; } + + std::string fcn_file_name (void) const { return file_name; } + +private: + + // The name of the file we parsed + std::string file_name; + + // No copying! + + octave_user_script (const octave_user_script& f); + + octave_user_script& operator = (const octave_user_script& f); + + DECLARE_OCTAVE_ALLOCATOR + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +// User-defined functions. class octave_user_function : public octave_function diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -2997,6 +2997,10 @@ { unwind_protect::add (safe_fclose, f); + octave_user_script *script = new octave_user_script (s, s, ""); + octave_call_stack::push (script); + unwind_protect::add (octave_call_stack::unwind_pop_script, 0); + unwind_protect_int (input_line_number); unwind_protect_int (current_input_column); @@ -3377,6 +3381,10 @@ bind_builtin_variable ("current_script_file_name", ff); + octave_user_script *script = new octave_user_script (ff, ff, ""); + octave_call_stack::push (script); + unwind_protect::add (octave_call_stack::unwind_pop_script, 0); + parse_and_execute (ffile); script_file_executed = true; @@ -3619,29 +3627,9 @@ } } - // XXX FIXME XXX -- the logic below fails for the following - // situation, because script files are not functions that can be - // entered into the call stack. - // - // foo.m: - // ----- - // function foo () - // bar; - // - // bar.m: - // ----- - // mfilename (); - // - // foo () - // ==> foo - // - // though it should report "bar". Perhaps we need a dummy function - // object that can be used for scripts to at least hold file names - // and some other information so we could store it on the call stack. - std::string fname; - octave_user_function *fcn = octave_call_stack::caller_script (); + octave_function *fcn = octave_call_stack::caller_user_script_or_function (); if (fcn) { @@ -3650,8 +3638,6 @@ if (fname.empty ()) fname = fcn->name (); } - else if (reading_script_file) - fname = curr_fcn_file_full_name; if (arg == "fullpathext") retval = fname; diff --git a/src/toplev.cc b/src/toplev.cc --- a/src/toplev.cc +++ b/src/toplev.cc @@ -109,8 +109,27 @@ return retval; } +octave_user_script * +octave_call_stack::do_caller_user_script (void) +{ + octave_user_script *retval = 0; + + for (iterator p = cs.begin (); p != cs.end (); p++) + { + octave_function *f = *p; + + if (f && f->is_user_script ()) + { + retval = dynamic_cast (f); + break; + } + } + + return retval; +} + octave_user_function * -octave_call_stack::do_caller_script (void) +octave_call_stack::do_caller_user_function (void) { octave_user_function *retval = 0; @@ -128,6 +147,34 @@ return retval; } +octave_function * +octave_call_stack::do_caller_user_script_or_function (void) +{ + octave_function *retval = 0; + + for (iterator p = cs.begin (); p != cs.end (); p++) + { + octave_function *f = *p; + + if (f && (f->is_user_script () || f->is_user_function ())) + { + retval = f; + break; + } + } + + return retval; +} + +void +octave_call_stack::unwind_pop_script (void *) +{ + octave_function *f = top (); + pop (); + assert (f && f->is_user_script ()); + delete f; +} + static void recover_from_exception (void) { diff --git a/src/toplev.h b/src/toplev.h --- a/src/toplev.h +++ b/src/toplev.h @@ -32,7 +32,7 @@ class octave_value; class octave_value_list; class octave_function; -class octave_user_function; +class octave_user_script; class tree_statement_list; class charMatrix; @@ -86,10 +86,7 @@ } // Current function (top of stack). - static octave_function *current (void) - { - return instance_ok () ? instance->do_current (): 0; - } + static octave_function *current (void) { return top (); } // Caller function, may be built-in. static octave_function *caller (void) @@ -97,10 +94,22 @@ return instance_ok () ? instance->do_caller (): 0; } - // First scripting language function on the stack. - static octave_user_function *caller_script (void) + // First script on the stack. + static octave_user_script *caller_script (void) { - return instance_ok () ? instance->do_caller_script (): 0; + return instance_ok () ? instance->do_caller_user_script (): 0; + } + + // First user-defined function on the stack. + static octave_user_function *caller_user_function (void) + { + return instance_ok () ? instance->do_caller_user_function (): 0; + } + + // First user-defined function on the stack. + static octave_function *caller_user_script_or_function (void) + { + return instance_ok () ? instance->do_caller_user_script_or_function (): 0; } static void push (octave_function *f) @@ -109,6 +118,11 @@ instance->do_push (f); } + static octave_function *top (void) + { + return instance_ok () ? instance->do_top (): 0; + } + static void pop (void) { if (instance_ok ()) @@ -119,6 +133,10 @@ // for use as an unwind_protect handler. static void unwind_pop (void *) { pop (); } + // A function for popping an octave_user_script from the top of the + // call stack that is suitable for use as an unwind_protect handler. + static void unwind_pop_script (void *); + static void clear (void) { if (instance_ok ()) @@ -132,14 +150,18 @@ static octave_call_stack *instance; - octave_function *do_current (void) { return cs.empty () ? 0 : cs.front (); } - octave_function *do_caller (void); - octave_user_function *do_caller_script (void); + octave_user_script *do_caller_user_script (void); + + octave_user_function *do_caller_user_function (void); + + octave_function *do_caller_user_script_or_function (void); void do_push (octave_function *f) { cs.push_front (f); } + octave_function *do_top (void) { return cs.empty () ? 0 : cs.front (); } + void do_pop (void) { if (! cs.empty ()) diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -1946,7 +1946,7 @@ } else if (args.length () == 0) { - octave_user_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) mlock (fcn->name ()); @@ -1980,7 +1980,7 @@ } else if (args.length () == 0) { - octave_user_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) mlock (fcn->name ()); @@ -2015,7 +2015,7 @@ } else if (args.length () == 0) { - octave_user_function *fcn = octave_call_stack::caller_script (); + octave_user_function *fcn = octave_call_stack::caller_user_function (); if (fcn) retval = mislocked (fcn->name ());