help-octave
[Top][All Lists]
Advanced

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

Re: Kind of a lookfor function


From: David Bateman
Subject: Re: Kind of a lookfor function
Date: Tue, 31 May 2005 05:34:06 +0200
User-agent: Mozilla Thunderbird 0.8 (X11/20040923)

What would be the right way to do this (even if it's not worth doing)?

Could a separate file with all the help texts be created when Octave
is compiled? That would be easy to search. I wonder how large the file
would be.

Alternatively a database could be created at compile time.


See the attached for a proof-of-concept of what I think is the right way of doing this. This is much better than treating the issue at compile time. There are several issues with this current implementation

1) Can't access the keywords and operators. This problem will go away if the code is integrated into octave's help.cc file
2) Assumes that all help is in texinfo form. See point 1)
3) Doesn't yet reproduce the regex logic in octave-forge/admin/make_index perl script to get the first sentence of non texinfo help files. In fact, without including regex into octave that is likely to take as much effort as what I've already done
4) Needs octave 2.9.x
5) Haven't written the function help yet

apart from these issues, this is a pretty good implementation of lookfor

Cheers
David

--
David Bateman                                address@hidden
Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 1 69 35 77 01 (Fax) 91193 Gif-Sur-Yvette FRANCE

The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary

/*

Copyright (C) 2005 David Bateman

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 2, 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, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.

*/

#include <config.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include "oct.h"
#include "oct-strstrm.h"
#include "defaults.h"
#include "fn-cache.h"

extern std::string get_help_from_file (const std::string& f);

#define DEFLEN 20

static std::string
pad (const std::string &s, const size_t len)
{
  std::string ret = s;
  for (size_t i = 0; i < len - s.length(); i++) 
    ret.append(" ");

  return ret;
}

// Dummy function that currently assumes the help is texinfo
static bool
looks_like_texinfo (const std::string& msg, size_t& p1)
{
  return true;
}

std::string 
first_help_sentence (const std::string &hin)
{
  // XXX FIXME XXX This only works correctly for texinfo help!!!
  size_t pos = 0;

  if (looks_like_texinfo (hin, pos))
    {
      // Get the parsed help string.
      OSSTREAM os;
      display_help_text (os, hin);
      std::string h = os.str ();

      while (1)
        {
          // Skip leading whitespace and get new line
          pos = h.find_first_not_of ("\n\t ", pos);
          size_t new_pos = h.find_first_of ('\n', pos);
          std::string line = h.substr (pos, new_pos-pos);
      
          // Skip lines starting in "-"
          if (line.find_first_of ('-') == 0)
            {
              pos = new_pos + 1;
              continue;
            }

          break;
        }

      // At start of real text. Get next line
      size_t new_pos = h.find_first_of ('\n', pos);
      std::string line = h.substr (pos, new_pos-pos);
      new_pos = line.find_first_of ('.');

      if (new_pos == NPOS)
        return line;
      else
        return line.substr (0, new_pos);
    }
  else
    {
      // Need to duplicate the logic from octave-forge/admin/make_index,
      // to select appropriate start of first sentence
      std::string h = hin;
      size_t pos = 0;

      // At start of real text. Get next line
      size_t new_pos = h.find_first_of ('\n', pos);
      std::string line = h.substr (pos, new_pos-pos);
      new_pos = line.find_first_of ('.');

      if (new_pos == NPOS)
        return line;
      else
        return line.substr (0, new_pos);
    }
}

DEFUN_DLD (lookfor, args, nargout, "lookfor function!!")
{
  octave_value_list retval;
  int nargin = args.length ();

  if (nargin != 1)
    {
      usage ("lookfor");
      return retval;
    }

  string_vector ret[2];

  if (args(0).is_string ())
    {
      std::string txt = args(0).string_value ();

      // XXX FIXME XXX Add test for keywords and operators here 
      

      // Check the symbol record table
      string_vector names
        = fbi_sym_tab->name_list (string_vector (), true);

      for (octave_idx_type i = 0; i < names.length (); i++)
        {
          std::string name = names (i);

          symbol_record *sr = lookup_by_name (name, 0);
          if (sr && sr->is_defined ())
            {
              std::string h = sr->help ();

              if (h.length () > 0 && h.find (txt, 0) != NPOS)
                {
                  ret[0].append (name);
                  ret[1].append (first_help_sentence (h));
                }
            }
        }

      string_vector dirs = Vload_path_dir_path.all_directories ();

      int len = dirs.length ();

      for (int i = 0; i < len; i++)
        {
          names = octave_fcn_file_name_cache::list (dirs[i]);

          if (! names.empty ())
            {
              for (int j = 0; j < names.length (); j++)
                {
                  std::string name = names (j);

                  // Strip extension
                  size_t len = name.length ();
                  if (name.substr (len-4) == ".oct")
                    name = name.substr (0, len - 4);
                  else if (name.substr (len-2) == ".m")
                    name = name.substr (0, len - 2);

                  // Check if already in symbol table
                  symbol_record *sr = fbi_sym_tab->lookup (names (j));

                  if (!sr)
                    {
                      // Check if this version is first in the path
                      string_vector tmp (2);
                      tmp(0) = name + ".oct";
                      tmp(1) = name + ".m";
                      std::string file_name = 
                        Vload_path_dir_path.find_first_of (tmp);

                      if (file_name == dirs[i] + names(j))
                        {
                          std::string h = get_help_from_file (name);
        
                          if (h.length () > 0 && h.find (txt, 0) != NPOS)
                            {
                              ret[0].append (name);
                              ret[1].append (first_help_sentence (h));
                            }
                        }
                    }
                }
            }
        }

      if (nargout != 0)
        {
          retval (1) = ret[1];
          retval (0) = ret[0];
        }
      else
        for (octave_idx_type i = 0; i < ret[0].length (); i++)
          octave_stdout << pad (ret[0](i), DEFLEN) << " " << ret[1](i) 
                        << std::endl;
    }
  else
    {
      error ("lookfor: argument must be a string");
    }

  return retval;
}

/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; End: ***
*/

reply via email to

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