(*******************************************************************)
(** Release history:                                              **)
(**    17th January 1985   version 1.0.0 First port to new world  **)
(*******************************************************************)
DEFINITION MODULE ScanS; 
(*
    Title    :  ScanS.ParseF? - simple string parsing utility
    LastEdit :  Wed Jan  9 16:58:15 1985
    Author   :  Graham Toal
    Acorn Computers VLSI Design Aids Group
*)


FROM Strings IMPORT String;
EXPORT QUALIFIED ParseF0, ParseF1, ParseF2, ParseF3, ParseF4;
PROCEDURE ParseF0 (Pattern :ARRAY OF CHAR; Data :String) :BOOLEAN;
PROCEDURE ParseF1 (Pattern :ARRAY OF CHAR; Data :String;
                   Replace1 :ARRAY OF CHAR; VAR Result1 :String
                   ) :BOOLEAN;
PROCEDURE ParseF2 (Pattern :ARRAY OF CHAR; Data :String;
                   Replace1 :ARRAY OF CHAR; VAR Result1 :String;
                   Replace2 :ARRAY OF CHAR; VAR Result2 :String
                   ) :BOOLEAN;
PROCEDURE ParseF3 (Pattern :ARRAY OF CHAR; Data :String;
                   Replace1 :ARRAY OF CHAR; VAR Result1 :String;
                   Replace2 :ARRAY OF CHAR; VAR Result2 :String;
                   Replace3 :ARRAY OF CHAR; VAR Result3 :String
                   ) :BOOLEAN;
PROCEDURE ParseF4 (Pattern :ARRAY OF CHAR; Data :String;
                   Replace1 :ARRAY OF CHAR; VAR Result1 :String;
                   Replace2 :ARRAY OF CHAR; VAR Result2 :String;
                   Replace3 :ARRAY OF CHAR; VAR Result3 :String;
                   Replace4 :ARRAY OF CHAR; VAR Result4 :String
                   ) :BOOLEAN;

(*------------------------------------------------------------------------*)
(*  ParseF?:                                                              *)
(*  ParseF is similar to the find/replace command used in both the Acorn  *)
(*  text-editors.  The interface is procedural, and the data it works     *)
(*  on is a single string.                                                *)
(*     ParseF1 takes as arguments a pattern string (usually a literal     *)
(*  in your program) and a data string.  The procedure tries to match     *)
(*  the pattern to the data, and any parts of the the data which both     *)
(*  matched the pattern and were wild (e.g. *[A-Z]) will be remembered    *)
(*  for insertion into the replace string.                                *)
(*     ParseF2, ParseF3 & ParseF4 offer identical facilities, but with    *)
(*  multiple replace strings - to take advantage of the ability to        *)
(*  perform the parse function once only.                                 *)
(*     The pattern string can contain both literal text, and a subset     *)
(*  of the type of regular expression which editors like 'sed' offer.     *)
(*  The special characters available are:                                 *)
(*                                                                        *)
(*  Valid in both PATTERN & REPLACE fields:                               *)
(*     |a   - control-A                                                   *)
(*     |!|a - control-A + 128                                             *)
(*     $    - newline                                                     *)
(*     \    - ensure that the next character is taken verbatim.           *)
(*                                                                        *)
(*  Valid in PATTERN field only:                                          *)
(*     .     - any character                                              *)
(*     @     - A-Z, a-z, 0-9, and '_'.                                    *)
(*     #     - 0-9                                                        *)
(*     [xyz] - any one of x, y, or z                                      *)
(*     a-z   - any one in the range a to z.                               *)
(*                                                                        *)
(*  The following prefixes can be applied to the above to                 *)
(*  modify their effect:                                                  *)
(*     *     - the shortest string of 0 or more                           *)
(*     ^     - the longest string of 1 or more                            *)
(*     ~     - anything but the following                                 *)
(*  And the following special case:                                       *)
(*     `     - invert the case sensitivity of searches for pattern        *)
(*             text following (default is case is insensitive)            *)
(*                                                                        *)
(*  Valid in REPLACE field only                                           *)
(*     %<field selector> - replace with appropriate field (see below)     *)
(*     &     - replace with entire string matched (special case of %&)    *)
(*                                                                        *)
(*  Field selectors take the following form:                              *)
(*     optional '+' or '-', followed by                                   *)
(*     one of '.', '@', '#', '[', '-', '*', '^' or '~', followed by       *)
(*     a digit in the range 0 to 9.                                       *)
(*                                                                        *)
(*  The significance of these fields is as follows:                       *)
(*     +/-    - force the case of the replacement text to be upper or     *)
(*              lower.                                                    *)
(* NOTE: +/- Not yet implemented - will be within 2 days. (at 5-Dec-84)   *)
(*     '^' etc. - select the first '^'-ed field, e.g. %* means            *)
(*                insert the data which matched the first field           *)
(*                which had a star in it.                                 *)
(*     0,1, etc. - Modify the above to read 'Nth' instead of 'first':     *)
(*                 N=0 is the first, N=1 the second etc.                  *)
(*                 (This is a bad nomenclature; we only use it here       *)
(*                  to be compatible with the ROM-ed Acorn editors.)      *)
(*                                                                        *)
(*  An example Pattern/replace string, and their effect on a data         *)
(*  string are given here:                                                *)
(*                                                                        *)
(*     Command := Strings.CopyCS ("draw fred.23 ");                       *)
(*     IF ParseF1 ("* draw* ^@\.^#* $", Command,                          *)
(*                 "Drawing cell %^0 vsn %^1$", Message) THEN             *)
(*                                                                        *)
(*  The fields are interpreted as:                                        *)
(*      Verify a sequence of spaces terminated by the first non-space.    *)
(*      match the text 'draw'.                                            *)
(*      Verify another sequence of spaces.                                *)
(*      Match the longest string of AlphaNumerics you can find.           *)
(*      Check that the next character is a dot (note the '\' escape       *)
(*        to avoid the special significance of '.'.                       *)
(*      Match the longest string of numbers you can find.                 *)
(*      Verify a (possibly null, as above) sequence of spaces.            *)
(*      Check that we are now at the end of the line.                     *)
(*                                                                        *)
(*  The replacement string is generated from:                             *)
(*     The literal text 'Drawing cell ',                                  *)
(*     The text which matched the first field which had a '^' in it,      *)
(*       i.e. 'fred'                                                      *)
(*     The literal text ' vsn ',                                          *)
(*     The text which matched the second field which had a '^' in it,     *)
(*       i.e. '23'                                                        *)
(*     And an end-of-line character.                                      *)
(*                                                                        *)
(*------------------------------------------------------------------------*)

END ScanS.
