[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: ***
*/