On 19/feb/08, at 15:00, David Bateman wrote:

This is looking good, however I have one issue with it. The signal INDEX
file contains the following snippet

signal >> Signal processing
Signals
 diric
 gauspuls
 gmonopuls

However the diric function etc end up classified into an "Unclassified" section rather than a "Signals" section. I therefore think that there is
still a slight error in your parsing code.. How robust is the parsing
code? Have you tested it on other octave-forge packages?

Regards
David


OK. this latest version also deals with:

- no newline at end of file
- lines left blank at random positions in the file
- a package with an INDEX file that just contains the line:
# dummy INDEX file
(??!!??)

It seems OK to me, though I will never be 100% sure there is no exotic construct left
that I have overlooked...

c.

# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1203455276 0
# Node ID 0152e282dee9ca890f586652a193c0b9cfaafeb9
# Parent  e4ac929fb3cefb4477e5fe80314bd239312ce41c
added describe command to pkg

diff -r e4ac929fb3ce -r 0152e282dee9 scripts/ChangeLog
--- a/scripts/ChangeLog Tue Feb 19 20:59:15 2008 +0000
+++ b/scripts/ChangeLog Tue Feb 19 21:07:56 2008 +0000
@@ -1,3 +1,10 @@ 2008-02-19  Bill Denney  <[EMAIL PROTECTED]
+2008-02-19 Carlo de Falco <[EMAIL PROTECTED]>
+
+       * pkg/pkg.m: Added the 'describe' ommand to pkg.
+       (pkg:parse_pkg_idx): Parses the INDEX file of a package.
+       (pkg:print_package_description): Formats the description of a
+       package to be output to screen.
+       
 2008-02-19  Bill Denney  <[EMAIL PROTECTED]>
 
        * time/datestr.m: Avoid confusion for datenum vectors that are 6
diff -r e4ac929fb3ce -r 0152e282dee9 scripts/pkg/pkg.m
--- a/scripts/pkg/pkg.m Tue Feb 19 20:59:15 2008 +0000
+++ b/scripts/pkg/pkg.m Tue Feb 19 21:07:56 2008 +0000
@@ -101,6 +101,29 @@
 ## @noindent
 ## splits the list of installed packages into those who are installed by
 ## the current user, and those installed by the system administrator.
+## @item describe
+## Show a short description of the named installed packages, with the option
+## '-verbose' also list functions provided by the package, e.g.:
+## @example
+##  pkg describe -verbose all
+## @end example
+## @noindent
+## will describe all installed packages and the functions they provide.
+## If one output is requested a cell of structure containing the
+## description and list of functions of each package is returned as
+## output rather than printed on screen:
+## @example
+##  desc = pkg ("describe", "secs1d", "image")
+## @end example
+## @noindent
+## If any of the requested packages is not installed, pkg returns an
+## error, unless a second output is requested:
+## @example
+##  [ desc, flag] = pkg ("describe", "secs1d", "image")
+## @end example
+## @noindent
+## @var{flag} will take one of the values "Not installed", "Loaded" or
+## "Not loaded" for each of the named packages.
 ## @item prefix
 ## Set the installation prefix directory. For example,
 ## @example
@@ -198,6 +221,8 @@ function [local_packages, global_package
     archprefix = tilde_expand (archprefix);
   endif
 
+  available_actions = {"list", "install", "uninstall", "load", "unload", 
"prefix", ...
+                      "local_list", "global_list", "rebuild", 
"build","describe"};
   ## Handle input
   if (length (varargin) == 0 || ! iscellstr (varargin))
     print_usage ();
@@ -227,8 +252,7 @@ function [local_packages, global_package
        if (! user_prefix)
          prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
        endif
-      case {"list", "install", "uninstall", "load", "unload", "prefix", ...
-           "local_list", "global_list", "rebuild", "build"}
+      case available_actions
        if (strcmp (action, "none"))
          action = varargin{i};
        else
@@ -365,6 +389,28 @@ function [local_packages, global_package
       endif
       build (files, deps, auto, verbose);
 
+    case "describe"
+      if (length (files) == 0)
+       error ("you must specify at least one package or 'all' when calling 
'pkg describe'");
+      endif
+      ## XXX FIXME: the name of the output variables is inconsistent
+      ##            with their content
+      switch (nargout)
+         case 0
+           describe (files, verbose, local_list, global_list);
+         case 1
+           pkg_desc_list = describe (files, verbose, local_list, ...
+                                global_list);
+           local_packages = pkg_desc_list;
+         case 2
+           [pkg_desc_list, flag] = describe (files, verbose, local_list, ...
+                                        global_list);
+           local_packages  = pkg_desc_list;
+           global_packages = flag;
+         otherwise
+           error ("you can request at most two outputs when calling 'pkg 
describe'");
+       endswitch
+               
     otherwise
       error ("you must specify a valid action for 'pkg'. See 'help pkg' for 
details");
   endswitch
@@ -900,9 +946,143 @@ function uninstall (pkgnames, handle_dep
 
 endfunction
 
+function [pkg_desc_list, flag] = describe (pkgnames, verbose, 
+                                          local_list, global_list)
+
+  ## Get the list of installed packages
+  installed_pkgs_lst = installed_packages(local_list, global_list);
+  num_packages       = length (installed_pkgs_lst);
+  
+
+  describe_all       = false;
+  if (any (strcmp ('all', pkgnames)))
+    describe_all         = true;
+    flag{1:num_packages} = "Not Loaded";
+    num_pkgnames         = num_packages;
+  else
+    num_pkgnames         = length (pkgnames);
+    flag{1:num_pkgnames} = "Not installed";
+  end
+
+  for i = 1:num_packages
+    curr_name= installed_pkgs_lst{i}.name;
+    if (describe_all)
+      name_pos = i;
+    else
+      name_pos = find(strcmp (curr_name, pkgnames));
+    end
+    if (!isempty(name_pos))
+      if (installed_pkgs_lst{i}.loaded)
+       flag{name_pos} = "Loaded";
+      else
+       flag{name_pos} = "Not loaded";
+      endif
+
+      pkg_desc_list{name_pos}.name = ...
+         installed_pkgs_lst{i}.name;
+      pkg_desc_list{name_pos}.description = ...
+         installed_pkgs_lst{i}.description;
+      pkg_desc_list{name_pos}.provides = ...
+         parse_pkg_idx(installed_pkgs_lst{i}.dir);
+
+    endif
+  endfor
+
+  non_inst = find(strcmp(flag,"Not installed"));
+  if (!isempty(non_inst) && (nargout<2))
+    non_inst_str = sprintf(" %s ",pkgnames{non_inst});
+    error("some packages are not installed: %s",non_inst_str);
+  endif
+
+  if (nargout == 0)
+    for i=1:num_pkgnames
+      print_package_description (pkg_desc_list{i}.name, 
+                                pkg_desc_list{i}.provides,  
+                                pkg_desc_list{i}.description,
+                                flag{i}, verbose);
+    endfor
+  endif
+
+endfunction
+
 ##########################################################
 ##        A U X I L I A R Y    F U N C T I O N S        ##
 ##########################################################
+
+## This function reads an INDEX file
+function [pkg_idx_struct] = parse_pkg_idx(packdir)
+
+  fINDEX = fullfile (packdir, "packinfo", "INDEX");
+
+  if (!exist(fINDEX, "file")  )
+    error("could not find any INDEX file in directory %s, \
+\ntry 'pkg rebuild all' to generate missing INDEX files", packdir);
+  endif    
+
+    
+  [fid, msg] = fopen(fINDEX,"r");
+  if (fid == -1)
+    error("the INDEX file %s could not be read: %s", 
+         fINDEX, msg);
+  endif
+  
+  cat_num = 1;
+  pkg_idx_struct{1}.category = "Uncategorized";
+  pkg_idx_struct{1}.functions = {};
+
+ 
+  line = fgetl(fid);
+  while ((isempty(strfind(line,">>"))) && (! feof (fid)))
+    line = fgetl(fid);
+  endwhile
+
+  while ((! feof (fid) ) || (line != -1))
+    if (!any(!isspace(line)) || (line(1) == "#") || any(line=="="))
+      ## Comments,  blank lines or comments about unimplemented 
+      ## functions: do nothing
+      ## XXX: probably comments and pointers to external functions
+      ## could be treated better when printing to screen?
+    elseif (!isempty(strfind(line,">>")))
+      ## Skip package name and description as they are in
+      ## DESCRIPTION already
+    elseif (!isspace(line(1)))
+      ## Category
+      if ( !isempty(pkg_idx_struct{cat_num}.functions))
+       pkg_idx_struct{++cat_num}.functions  = {};
+      endif
+      pkg_idx_struct{cat_num}.category = deblank(line);
+    else
+      ## Function names
+      while (any(!isspace(line)))
+       [fun_name, line] = strtok(line);
+       pkg_idx_struct{cat_num}.functions{end+1}  = deblank(fun_name);
+      endwhile
+    endif
+    line = fgetl(fid);
+  endwhile
+  fclose (fid);
+endfunction
+
+function print_package_description (pkg_name, pkg_idx_struct, 
+                                   pkg_desc, status, verbose)
+
+  printf("---\nPackage name:\n\t%s\n", pkg_name);
+  printf("Short description:\n\t%s\n", pkg_desc);
+  printf("Status:\n\t%s\n", status);
+  if (verbose)
+    printf("---\nProvides:\n");    
+    for i=1:length(pkg_idx_struct)
+      if (!isempty(pkg_idx_struct{i}.functions))
+       printf("%s\n", pkg_idx_struct{i}.category);
+       for j=1:length(pkg_idx_struct{i}.functions)
+         printf("\t%s\n", pkg_idx_struct{i}.functions{j});
+       endfor
+      endif
+    endfor
+  endif
+
+endfunction
+
 
 function pth = absolute_pathname (pth)
   [status, msg, msgid] = fileattrib(pth);
@@ -1580,7 +1760,7 @@ endfunction
 
 ## Creates an INDEX file for a package that doesn't provide one.
 ##   'desc'  describes the package.
-##   'dir'   is the 'inst' direcotyr in temporary directory.
+##   'dir'   is the 'inst' direcotry in temporary directory.
 ##   'INDEX' is the name (including path) of resulting INDEX file.
 function write_INDEX (desc, dir, INDEX, global_install)
   ## Get names of functions in dir
@@ -2104,3 +2284,5 @@ function dep = is_architecture_dependent
     endif
   endfor
 endfunction
+
+
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Octave-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/octave-dev

Reply via email to