help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: doubts about functions declared in parse.h ...


From: John W. Eaton
Subject: Re: doubts about functions declared in parse.h ...
Date: Sun, 13 Mar 2005 10:56:44 -0500

On 13-Mar-2005, Alberto Francisco Martin Huertas <address@hidden> wrote:

| Hello. I'm interested into source a m file in a C++ DLF function with the
| following behaviour:
| 
| $ cat script.m
| a=3;
| $ octave
| octave:1> a=1
| a=1
| octave:2> exfun ("script.m", "a")
| ans = 3
| octave:3> a
| a = 1
| 
| and the exfun C++ function you have provided to me has this behaviour:
| 
| $ cat script.m
| a=3;
| $ octave
| octave:1> a=1
| a=1
| octave:2> exfun ("script.m", "a")
| ans = 3
| octave:3> a
| a = 3

Sorry, i misunderstood the original question.

| so I would like to source a script having a local scope in my C++
| function. Is that posible ?

Yes, see the attached function.  The difference between this one and
the previous version I sent is that it sets up a local symbol table.
It should even work if "exfun" is called recursively.  The operations
performed to set up the symbol table and handle recursion are a subset
of what is done for .m files (see src/ov-usr-fcn.cc).

But instead of doing all of this, why not convert your script to a
function so that it limits the scope of the variables it contains?

Also, are you sure you really need to be writing C++?  I think many
people start doing that because they can, not because it is necessary.
In this particular case, you are getting pretty far off into the
internals of Octave, which are always subject to change.  Writing this
code in C++ means that it may break in the future if the internals of
Octave are modified.

jwe

#include <octave/oct.h>
#include <octave/parse.h>
#include <octave/unwind-prot.h>

static void
pop_symbol_table_context (void *table)
{
  symbol_table *tmp = static_cast<symbol_table *> (table);
  tmp->pop_context ();
}

static void
clear_symbol_table (void *table)
{
  symbol_table *tmp = static_cast<symbol_table *> (table);
  tmp->clear ();
}

DEFUN_DLD (exfun, args, , "exfun (file, sym)")
{
  octave_value_list retval;

  static symbol_table *local_sym_tab = new symbol_table ();

  static int call_depth = 0;

  if (args.length () == 2)
    {
      std::string fname = args(0).string_value ();
      std::string sym = args(1).string_value ();

      if (! error_state)
        {
          unwind_protect::begin_frame ("exfun");

          // Force local symbols to be undefined again when this
          // function exits.

          unwind_protect::add (clear_symbol_table, local_sym_tab);

          // Save old and set current symbol table context, for
          // eval_undefined_error().

          unwind_protect_ptr (curr_caller_sym_tab);
          curr_caller_sym_tab = curr_sym_tab;

          unwind_protect_ptr (curr_sym_tab);
          curr_sym_tab = local_sym_tab;

          // XXX FIXME XXX -- we might want to limit max recursion
          // depth.

          unwind_protect_int (call_depth);
          call_depth++;

          if (call_depth > 1)
            {
              local_sym_tab->push_context ();
              unwind_protect::add (pop_symbol_table_context, local_sym_tab);
            }

          source_file (fname);

          if (! error_state)
            {
              symbol_record *sr = curr_sym_tab->lookup (sym);

              if (sr)
                retval(0) = sr->def ();
              else
                error ("exfun: symbol \"%s\" not found", sym.c_str ());
            }

          unwind_protect::run_frame ("exfun");
        }
    }
  else
    print_usage ("exfun");

  return retval;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]