home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / LIBRARY / GLOB.SA < prev    next >
Text File  |  1995-02-05  |  6KB  |  146 lines

  1. -- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
  2. -- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
  3. -- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
  4. -- the file "Doc/License" of the Sather distribution.  The license is also   --
  5. -- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
  6. --------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
  7.  
  8. -- glob.sa: Unix style "globbing" of strings.
  9. -------------------------------------------------------------------
  10. class GLOB is
  11.    -- Unix "glob"-style string patterns are what the various shells 
  12.    -- in Unix use to specify sets of file names. They are used in the
  13.    -- Sather interpreter to specify class names, etc. This class takes
  14.    -- a pattern string and a test string and determines whether
  15.    -- the test string matches the pattern.
  16.    -- 
  17.    -- Here are the components of a glob pattern:
  18.    -- 
  19.    -- 1) char 
  20.    -- Any pattern character except for the special characters 
  21.    -- "[{?*\" must be matched exactly in the text string.
  22.    -- 
  23.    -- 2) '\' char
  24.    -- The backslash character is used as an escape to enable matching 
  25.    -- of the special characters. The backslash may be followed by any
  26.    -- character and the pattern matches that character.
  27.    -- 
  28.    -- 3) '[' ... ']'
  29.    -- If the left bracket character '[' appears unescaped, then it
  30.    -- must be followed by a sequence of characters and a right bracket.
  31.    -- This pattern matches any single character in the list. If a 
  32.    -- right bracket appears immediately after the left bracket, it is 
  33.    -- treated as an ordinary character rather than as the closing 
  34.    -- bracket. All characters between the two brackets except '-' are 
  35.    -- taken to be themselves (i.e. they aren't special or escaped). 
  36.    -- Sequences of the form "char1 '-' char2" are treated as a 
  37.    -- shorthand for a list of all the characters alphabetically 
  38.    -- between "char1" and "char2". '-' may be included in the set by 
  39.    -- making it the first or last character.
  40.    -- 
  41.    -- 3) '{' str, str, ... '}'
  42.    -- If the left brace character '{' appears unescaped, then it
  43.    -- must be followed by a comma-separated list of strings. Nothing
  44.    -- is escaped 
  45.    -- 
  46.    -- 4) '?'
  47.    -- A question mark matches an arbitrary single character. 
  48.    -- 
  49.    -- 5) '*'
  50.    -- An asterisk matches zero or more arbitrary characters.
  51.  
  52.    is_legal_pattern(s:STR):STR is
  53.       -- Void if `s' is a legal pattern string, an error message if
  54.       -- not.
  55.       in_bracket:BOOL;        -- True if between brackets.
  56.       after_slash:BOOL;        -- True if immediately after a backslash.
  57.       loop i::=s.ind!; c::=s[i];
  58.      if in_bracket then
  59.         if c='[' then
  60.         return "Error in glob pattern at character " + i +
  61.            ", unescaped bracket within brackets." 
  62.         elsif c=']' then in_bracket:=false end;
  63.      elsif c='[' then in_bracket:=true end;
  64.      if after_slash then
  65.         if "[]?*\\".contains(c) then after_slash:=false
  66.         else return "Error in glob pattern at character " + i + 
  67.            ", illegal character after backslash." end;
  68.      elsif c='\\' then after_slash:=true end end;
  69.       if in_bracket then
  70.      return "Error in glob pattern, no closing bracket." end;
  71.       if after_slash then
  72.      return "Error in glob pattern, final backslash." end;
  73.       return void end;
  74.    
  75.    pattern_matches(pat,s:STR):BOOL is
  76.       -- True if the glob pattern `pat' matches the string `s'.
  77.       return pattern_matches(pat,s,0,0) end;
  78.    
  79.    pattern_matches(pat,s:STR,pst,sst:INT):BOOL is
  80.       -- True if the pattern `pat' starting at character `pst' 
  81.       -- matches the string `s' starting at character `sst'.
  82.       if pst=pat.size then return sst=s.size end;
  83.       c::=pat[pst];        -- The pattern character.
  84.       case c
  85.       when '\\' then
  86.      if pat.size=pst+1 then return false end; -- Error in pattern.
  87.      c2::=pat[pst+1];    -- The next character
  88.      case c2
  89.      when '[', ']', '?', '*', '\\' then
  90.         if s.size=sst then return false end; -- String used up.
  91.         if s[sst]=c2 then 
  92.            return pattern_matches(pat,s,pst+2,sst+1) 
  93.         else return false end;
  94.      else return false end; -- Error in pattern.
  95.       when '[' then
  96.      if s.size=sst then return false end; -- No chars left to match.
  97.      rb::=pat.search(']',pst+1); -- Closing right bracket index.
  98.      if rb=-1 then return false end; -- Error in pattern.
  99.      i::=pst+1;
  100.      loop until!(i=rb); -- Indices between brackets.
  101.         c:=pat[i];
  102.         case c
  103.         when '\\' then c2::=pat[i+1];
  104.            case c2
  105.            when  '[', ']', '?', '*', '\\' then
  106.           if s[sst]=c2 then
  107.              return pattern_matches(pat,s,rb+1,sst+1) end;
  108.            else return false end; -- Error in pattern.
  109.            i:=i+1;        -- Extra increment to position.
  110.         when '-' then
  111.            if i=pst+1 then
  112.           if s[sst]='-' then -- First character in brackets.
  113.              return pattern_matches(pat,s,rb+1,sst+1) end;
  114.            else        -- Check range.
  115.           if pat[i-1]<s[sst] and s[sst]<pat[i+1] then
  116.              return pattern_matches(pat,s,rb+1,sst+1) end;
  117.            end;
  118.         when  '[', ']', '?', '*' then
  119.            return false;    -- Error in pattern.
  120.         else
  121.            if s[sst]=c then 
  122.           return pattern_matches(pat,s,rb+1,sst+1) end end;
  123.         i:=i+1 end;
  124.      return false;        -- Nothing matched.
  125.       when ']' then return false -- Error in pattern.
  126.       when '?' then
  127.      if s.size=sst then return false end; -- String used up.     
  128.      return pattern_matches(pat,s,pst+1,sst+1) -- ? matches 1 char.
  129.       when '*' then
  130.      if pst=pat.size-1 then return true end; -- * matches anything.
  131.      nsst::=sst;        -- Next starting position.
  132.      loop until!(nsst>=s.size); -- Done when string is used up.
  133.         if pattern_matches(pat,s,pst+1,nsst) then return true end;
  134.         nsst:=nsst+1 end;
  135.      return false;        -- No matches.
  136.       else            -- Ordinary character, must match.
  137.      if s.size=sst then return false -- String used up.     
  138.      elsif s[sst]=c then 
  139.         return pattern_matches(pat,s,pst+1,sst+1)
  140. --       else return false end end end;                                         -- NLP
  141.          end; end; return false; end;                                           -- NLP
  142.  
  143. end; -- class GLOB
  144.  
  145. -------------------------------------------------------------------
  146.