changeset 3789:2a257be5e488

[project @ 2001-02-09 04:12:30 by jwe]
author jwe
date Fri, 09 Feb 2001 04:12:31 +0000
parents c60b54937cfe
children 1e0d844b8f54
files scripts/strings/base2dec.m scripts/strings/bin2dec.m scripts/strings/dec2base.m scripts/strings/dec2bin.m scripts/strings/dec2hex.m scripts/strings/hex2dec.m scripts/strings/patch scripts/strings/strjust.m
diffstat 8 files changed, 376 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/scripts/strings/base2dec.m
@@ -0,0 +1,85 @@
+## Copyright (C) 2000 Daniel Calvelo
+##
+## 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, 59 Temple Place - Suite 330, Boston, MA
+## 02111-1307, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} base2dec (@var{s}, @var{b})
+## Convert @var{s} from a string of digits of base @var{b} into an
+## integer.
+##
+## @example
+## base2dec ("11120", 3)
+##      @result{} 123
+## @end example
+##
+## If @var{s} is a matrix, returns a column vector with one value per
+## row of @var{s}.  If a row contains invalid symbols then the
+## corresponding value will be NaN.  Rows are right-justified before
+## converting so that trailing spaces are ignored.
+##
+## If @var{b} is a string, the characters of @var{b} are used as the
+## symbols for the digits of @var{s}. Space (' ') may not be used as a
+## symbol.
+##
+## @example
+## base2dec ("yyyzx", "xyz")
+##      @result{} 123
+## @end example
+##
+## @end deftypefn
+## @seealso{dec2base, dec2bin, bin2dec, hex2dec, dec2hex}
+
+## Author: Daniel Calvelo <>
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
+
+function out = base2dec (d, base)
+
+  if (nargin != 2)
+    usage ("n = base2dec('d', base)");
+  endif
+
+  symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  if (isstr (base))
+    symbols = base;
+    base = length (symbols);
+    if (any (diff (sort (toascii (symbols))) == 0))
+      error ("base2dec: symbols representing digits must be unique.");
+    endif
+  elseif (! is_scalar (base))
+    error ("base2dec: cannot convert from several bases at once.");
+  elseif (base < 2 || base > length (symbols))
+    error ("base2dec: base must be between 2 and 36 or a string of symbols");
+  else
+    d = toupper (d);
+  endif
+
+  ## Right justify the values before anything else.
+  d = strjust (d, "right");
+
+  ## Lookup value of symbols in symbol table, with invalid symbols
+  ## evaluating to NaN and space evaluating to 0.
+  table = NaN * ones (256, 1);
+  table (toascii (symbols (1 : base))) = 0 : base-1;
+  table (toascii (" ")) = 0;
+  d = reshape (table (toascii (d)), size (d));
+
+  ## Multiply the resulting digits by the appropriate power and
+  ## sum the rows.
+  out = d * (base .^ (columns(d)-1 : -1 : 0)');
+
+endfunction
--- a/scripts/strings/bin2dec.m
+++ b/scripts/strings/bin2dec.m
@@ -1,4 +1,4 @@
-## Copyright (C) 1996 Kurt Hornik
+## Copyright (C) 2000 Daniel Calvelo
 ##
 ## This file is part of Octave.
 ##
@@ -18,31 +18,30 @@
 ## 02111-1307, USA.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} bin2dec (@var{s})
-## Return the decimal number corresponding to the binary number
-## represented by the string @var{s}.  For example,
+## @deftypefn {Function File} {} hex2dec (@var{s})
+## Return the decimal number corresponding to the binary number stored
+## in the string @var{s}.  For example,
 ##
 ## @example
-## bin2dec ("1110")
+## hex2dec ("1110")
 ##      @result{} 14
 ## @end example
+##
+## If @var{s} is a string matrix, returns a column vector of converted
+## numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
 ## @end deftypefn
+##
+## @seealso{dec2hex, base2dec, dec2base, bin2dec, dec2bin}
 
-## Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
-## Adapted-By: jwe
+## Author: Daniel Calvelo
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
 
-function y = bin2dec (x)
+function d = bin2dec (h)
 
   if (nargin != 1)
-    usage ("bin2dec (x)");
-  endif
-
-  x = toascii (x) - toascii ("0");
-
-  if (all (x == 0 | x == 1))
-    y = sum ((x .* (ones (rows (x), 1) * 2.^((length (x) - 1) : -1 : 0)))')';
+    usage ("bin2dec (b)");
   else
-    error ("bin2dec: argument must be a string of zeros and ones");
+    d = base2dec (h, 2);
   endif
 
 endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/strings/dec2base.m
@@ -0,0 +1,84 @@
+## Copyright (C) 2000 Daniel Calvelo
+##
+## 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, 59 Temple Place - Suite 330, Boston, MA
+## 02111-1307, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dec2base (@var{n}, @var{b})
+## Return a string of symbols in base @var{b} corresponding to the
+## the nonnegative integer @var{n}.
+##
+## @example
+## dec2base (123, 3)
+##      @result{} "11120"
+## @end example
+##
+## If @var{n} is a vector, return a string matrix with one row per value,
+## padded with leading zeros to the width of the largest value.
+##
+## If @var{b} is a string then the characters of @var{b} are used as
+## the symbols for the digits of @var{n}.  Space (' ') may not be used
+## as a symbol.
+##
+## @example
+## dec2base (123, "aei")
+##      @result{} "eeeia"
+## @end example
+## @end deftypefn
+##
+## @seealso{base2dec, dec2bin, bin2dec, hex2dec, dec2hex}
+
+## Author: Daniel Calvelo <>
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
+
+function out = dec2base (d, base)
+
+  if (nargin != 2)
+    usage("dec2base (n, base)");
+  endif
+
+  if (prod (size (d)) != length (d))
+    error("dec2base: cannot convert matrices.");
+  elseif (any (d < 0 | d != fix (d)))
+    error("dec2base: can only convert non-negative integers.")
+  endif
+
+  symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  if (isstr (base))
+    symbols = base;
+    base = length (symbols);
+    if any (diff (sort (toascii (symbols))) == 0)
+      error ("dec2base: symbols representing digits must be unique.");
+    endif
+  elseif (! is_scalar (base))
+    error ("dec2base: cannot convert from several bases at once.");
+  elseif (base < 2 || base > length (symbols))
+    error ("dec2base: base must be between 2 and 36 or a string of symbols");
+  endif
+  
+  ## determine number of digits required to handle all numbers
+  maxLen = floor (log (max (max (d), 1)) ./ log (base)) + 1;
+  
+  ## determine digits for each number
+  power = ones (length (d), 1) * (base .^ (maxLen-1 : -1 : 0));
+  d = d(:) * ones (1, maxLen);
+  digits = floor (rem (d, base*power) ./ power);
+
+  ## convert digits to symbols
+  out = reshape (symbols (digits+1), size (digits));
+
+endfunction
--- a/scripts/strings/dec2bin.m
+++ b/scripts/strings/dec2bin.m
@@ -1,4 +1,4 @@
-## Copyright (C) 1996 Kurt Hornik
+## Copyright (C) 2001 Daniel Calvelo
 ##
 ## This file is part of Octave.
 ##
@@ -26,44 +26,22 @@
 ## dec2bin (14)
 ##      @result{} "1110"
 ## @end example
+##
+## If @var{n} is a vector, returns a string matrix, one row per value,
+## padded with leading zeros to the width of the largest value.
 ## @end deftypefn
+##
+## @seealso{bin2dec, dec2base, base2dec, hex2dec, dec2hex}
 
-## Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
-## Adapted-By: jwe
+## Author: Daniel Calvelo
+## 2001-02-02 Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
 
-function y = dec2bin (x)
+function h = dec2bin (d)
 
   if (nargin != 1)
-    usage ("dec2bin (x)");
+    usage ("dec2bin (b)");
+  else
+    h = dec2base (d, 2);
   endif
 
-  [nr, nc] = size (x);
-
-  len = nr * nc;
-
-  x = reshape (x, 1, len);
-
-  eleo = empty_list_elements_ok;
-  unwind_protect
-    empty_list_elements_ok = 1;
-    y = [];
-    for i = 1:len
-      tmp = x (i);
-      if (tmp == round (tmp) && tmp >= 0)
-        while (tmp >= 2)
-          z = fix (tmp ./ 2);
-          y = [y, tmp - 2 * z];
-          tmp = z;
-        endwhile
-        y = [y, tmp];
-      else
-        error ("dec2hex: invalid conversion");
-      endif
-    endfor
-    y = fliplr (y);
-    y = setstr (y + toascii ("0"));
-  unwind_protect_cleanup
-    empty_list_elements_ok = eleo;
-  end_unwind_protect
-
 endfunction
--- a/scripts/strings/dec2hex.m
+++ b/scripts/strings/dec2hex.m
@@ -1,4 +1,4 @@
-## Copyright (C) 1996 Kurt Hornik
+## Copyright (C) 2000 Daniel Calvelo
 ##
 ## This file is part of Octave.
 ##
@@ -19,44 +19,29 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} dec2hex (@var{n})
-## Return the hexadecimal number corresponding to the nonnegative decimal
-## number @var{n}, as a string.  For example,
+## Return the hexadecimal string corresponding to the nonnegative 
+## integer @var{n}.  For example,
 ##
 ## @example
 ## dec2hex (2748)
-##      @result{} "abc"
+##      @result{} "ABC"
 ## @end example
+##
+## If @var{n} is a vector, returns a string matrix, one row per value,
+## padded with leading zeros to the width of the largest value.
 ## @end deftypefn
+##
+## @seealso{hex2dec, dec2base, base2dec, bin2dec, dec2bin}
 
-## Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
-## Adapted-By: jwe
+## Author: Daniel Calvelo
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
 
 function h = dec2hex (d)
 
   if (nargin != 1)
-    usage ("dec2hex (d)");
+    usage ("dec2hex (b)");
+  else
+    h = dec2base (d, 16);
   endif
 
-  [nr, nc] = size (d);
-
-  len = nr * nc;
-
-  d = reshape (d, 1, len);
-
-  eleo = empty_list_elements_ok;
-  unwind_protect
-    empty_list_elements_ok = 1;
-    h = "";
-    for i = 1:len
-      tmp = d (i);
-      if (tmp == round (tmp))
-        h = sprintf ("%s%x", h, tmp);
-      else
-        error ("dec2hex: invalid conversion");
-      endif
-    endfor
-  unwind_protect_cleanup
-    empty_list_elements_ok = eleo;
-  end_unwind_protect
-
 endfunction
--- a/scripts/strings/hex2dec.m
+++ b/scripts/strings/hex2dec.m
@@ -1,4 +1,4 @@
-## Copyright (C) 1996 Kurt Hornik
+## Copyright (C) 2000 Daniel Calvelo
 ##
 ## This file is part of Octave.
 ##
@@ -19,7 +19,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} hex2dec (@var{s})
-## Return the decimal number corresponding to the hexadecimal number stored
+## Returns the integer corresponding to the hexadecimal number stored
 ## in the string @var{s}.  For example,
 ##
 ## @example
@@ -28,35 +28,22 @@
 ## hex2dec ("12b")
 ##      @result{} 299
 ## @end example
+##
+## If @var{s} is a string matrix, returns a column vector of converted
+## numbers, one per row of @var{s}.  Invalid rows evaluate to NaN.
 ## @end deftypefn
+##
+## @seealso{dec2hex, base2dec, dec2base, bin2dec, dec2bin}
 
-## Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
-## Adapted-By: jwe
+## Author: Daniel Calvelo
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
 
 function d = hex2dec (h)
 
   if (nargin != 1)
-    usage ("hex2dec (x)");
-  endif
-
-  if (isstr (h))
-    nr = rows (h);
-    d = zeros (nr, 1);
-    for i = 1:nr
-      s = h (i, :);
-      if (isxdigit (s))
-        tmp = sscanf (s, "%x");
-        if (isempty (tmp))
-          error ("hex2dec: invalid conversion");
-        else
-          d (i) = tmp;
-        endif
-      else
-        error ("hex2dec: argument must be a string of hexadecimal digits");
-      endif
-    endfor
+    usage ("hex2dec (b)");
   else
-    error ("hex2dec: expecting a string argument");
+    d = base2dec (h, 16);
   endif
 
 endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/strings/patch
@@ -0,0 +1,81 @@
+*** strrep.m-2.1.28	Tue May  2 01:39:24 2000
+--- strrep.m	Fri May 12 08:21:15 2000
+***************
+*** 45,70 ****
+      t = s;
+      return;
+    endif
+    ind = findstr (s, x, 0);
+!   len = length (ind);
+!   if (len == 0)
+      t = s;
+!   else
+!     save_empty_list_elements_ok = empty_list_elements_ok;
+!     unwind_protect
+!       empty_list_elements_ok = 1;
+!       l_x = length (x);
+!       tmp = s (1 : ind (1) - 1);
+!       t = strcat (tmp, y);
+!       for k = 1 : len - 1
+!         tmp = s (ind (k) + l_x : ind (k+1) - 1);
+!         t = strcat (t, tmp, y);
+!       endfor
+!       tmp = s (ind(len) + l_x : length (s));
+!       t = [t, tmp];
+!     unwind_protect_cleanup
+!       empty_list_elements_ok = save_empty_list_elements_ok;
+!     end_unwind_protect
+    endif
+  
+  endfunction
+--- 45,94 ----
+      t = s;
+      return;
+    endif
++ 
+    ind = findstr (s, x, 0);
+!   if (length(ind) == 0)
+      t = s;
+! 
+!   elseif (length(y) > 0)      # replacement
+!     ## Copy the parts of s that aren't being replaced.  This is done
+!     ## with an index vector, with jumps where each search string
+!     ## is found.  For a jump of 0 (target length == replacement length)
+!     ## the index is just cumsum ( ones (length (s))).  For non-zero
+!     ## jumps, add the jump size to the ones vector at each found position.
+!     jump = length(y) - length(x);
+!     if (jump > 0)     # s expands
+!       di = ones(size(s));
+!       di (ind) = 1 + jump * ones (length (ind), 1);
+!       t (cumsum (di)) = s;
+!       if (size(s,1) == 1)
+! 	t = t';
+!       endif
+!     elseif (jump < 0) # s contracts
+!       di = ones (jump * length (ind) + length (s), 1);
+!       di (ind + jump * [0:length(ind)-1]) = 1 - jump * ones(length(ind), 1);
+!       t = s (cumsum (di));
+!     else              # s stays the same length
+!       t = s;
+!     endif
+! 
+!     ## Now, substitute a copy of the replacement string whereever the
+!     ## search string was found.  Note that we must first update the
+!     ## target positions to account for any expansion or contraction
+!     ## of s that may have occurred.
+!     ind = ind + jump * [ 0 : length (ind) - 1 ];
+!     repeat = [1 : length (y)]' * ones (1, length (ind));
+!     dest = ones (length (y), 1) * ind + repeat - 1;
+!     t (dest) = y (repeat);
+! 
+!   else                        # deletion
+!     ## Build an index vector of all locations where the target was found
+!     ## in the search string, and zap them. 
+!     t = toascii(s);
+!     repeat = [1 : length (x)]' * ones (1, length (ind));
+!     delete = ones (length (x), 1) * ind + repeat - 1;
+!     t (delete) = [];
+!     t = setstr(t);
+    endif
+  
+  endfunction
new file mode 100644
--- /dev/null
+++ b/scripts/strings/strjust.m
@@ -0,0 +1,74 @@
+## Copyright (C) 2000 Paul Kienzle
+##
+## 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, 59 Temple Place - Suite 330, Boston, MA
+## 02111-1307, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} strjust (@var{s}, ["left"|"right"|"center"])
+## Shift the non-blank text of @var{s} to the left, right or center of
+## the string.  If @var{s} is a string array, justify each string in the
+## array.  Null characters are replaced by blanks.  If no justification
+## is specified, then all rows are right-justified.
+## @end deftypefn
+
+function x = strjust (x, just)
+
+  if (nargin < 1 || nargin > 2)
+    usage ("strjust (s, ['left'|'right'|'center'])");
+  endif
+
+  if (nargin == 1)
+    just = "right";
+  endif
+
+  just = tolower (just);
+
+  dfi = do_fortran_indexing;
+  unwind_protect
+    do_fortran_indexing = 1;
+
+    ## convert nulls to blanks
+    idx = find (toascii (x) == 0);
+    if (! isempty (idx))
+      x(idx) = " ";
+    endif
+
+    ## For all cases, left, right and center, the algorithm is the same.
+    ## Find the number of blanks at the left/right end to determine the
+    ## shift, rotate the row index by using mod with that shift, then
+    ## translate the shifted row index into an array index.
+    [nr, nc] = size (x);
+    idx = (x' != " ");
+    if (strcmp (just, "right"))
+      [N, hi] = max (cumsum (idx));
+      shift = hi;
+    elseif (strcmp (just, "left"))
+      [N, lo] = max (cumsum (flipud (idx)));
+      shift = (nc - lo);
+    else
+      [N, hi] = max (cumsum (idx));
+      [N, lo] = max (cumsum (flipud (idx)));
+      shift = ceil (nc - (lo-hi)/2);
+    endif
+    idx = rem (ones(nr,1)*[0:nc-1] + shift'*ones(1,nc), nc);
+    x = x (idx*nr + [1:nr]'*ones(1,nc));
+
+  unwind_protect_cleanup
+    do_fortran_indexing = dfi;
+  end_unwind_protect
+
+endfunction