summaryrefslogtreecommitdiff
path: root/Build/source/utils/m-tx/mtx-0.60d/utility.pas
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2012-07-12 14:32:18 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2012-07-12 14:32:18 +0000
commit9f5608ba2efae21382aa973dc6095686c97b6c0e (patch)
tree9869762cf231ec6cd33923478a3f8ef7e2a6f5f3 /Build/source/utils/m-tx/mtx-0.60d/utility.pas
parentfd09c28d8785ca8ed5f57902031cb29541fc8f3f (diff)
utils/mtx: Renamed into utils/m-tx
git-svn-id: svn://tug.org/texlive/trunk@27015 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/m-tx/mtx-0.60d/utility.pas')
-rw-r--r--Build/source/utils/m-tx/mtx-0.60d/utility.pas194
1 files changed, 194 insertions, 0 deletions
diff --git a/Build/source/utils/m-tx/mtx-0.60d/utility.pas b/Build/source/utils/m-tx/mtx-0.60d/utility.pas
new file mode 100644
index 00000000000..42cc76d15d5
--- /dev/null
+++ b/Build/source/utils/m-tx/mtx-0.60d/utility.pas
@@ -0,0 +1,194 @@
+unit utility; { DPL 2004-03-22 }
+
+{ Utilities, mainly aids to parsing }
+
+interface
+
+function equalsIgnoreCase(s1, s2: string): boolean;
+function startsWithIgnoreCase(s1, s2: string): boolean;
+function endsWith(s1, s2: string): boolean;
+function startsWithBracedWord (P: string): boolean;
+function GetNextWord (var s: string; Delim, Term: char): string;
+function NextWord (s: string; Delim, Term: char): string;
+function wordCount (s: string): integer;
+function plural (n: integer): string;
+function curtail (var s: string; c: char): integer;
+ { Remove last character if it equals c and return its position;
+ otherwise return 0 }
+function toString(n: integer): string;
+procedure trim(var s: string);
+function digit(c: char): integer;
+function match(source, pattern: string): boolean;
+function translate(source, pattern, target: string): string;
+procedure grep(var source, pattern, target: string);
+ { See Implementation for what this currently does. }
+
+implementation uses strings;
+
+const blank = ' '; dummy = #0;
+
+function wordCount (s: string): integer;
+ var i, n: integer;
+ begin if length(s)=0 then
+ begin wordCount:=0; exit; end;
+ if s[1]=blank then n:=0 else n:=1;
+ for i:=1 to length(s)-1 do
+ if (s[i]=blank) and (s[i+1]<>blank) then inc(n);
+ wordCount:=n;
+ end;
+
+function GetNextWord (var s: string; Delim, Term: char): string;
+{ A delimiter is a character that separates words, but forms no part
+ of them. A terminator is a character that appears at the end of
+ a word. }
+ var n, start, last: integer;
+begin last:=length(s); n:=1;
+ while (n<=last) and (s[n] = Delim) do inc(n);
+ start:=n;
+ while (n<=last) and not (s[n] in [Delim,Term]) do inc(n);
+ if (n<=last) and (s[n] = Term) then inc(n);
+ GetNextWord:=substr(s,start,n-start);
+ while (n<=last) and (s[n] = Delim) do inc(n);
+ predelete(s,n-1);
+end;
+
+function NextWord (s: string; Delim, Term: char): string;
+ begin NextWord:=GetNextWord(s,Delim,Term); end;
+
+function plural (n: integer): string;
+ begin if n=1 then plural:='' else plural:='s'; end;
+
+function curtail (var s: string; c: char): integer;
+ var l: integer;
+ begin l:=length(s); curtail:=0;
+ if s[l]=c then begin shorten(s,l-1); curtail:=l; end;
+ end;
+
+function toString(n: integer): string;
+ var s: string;
+begin str(n,s); toString:=s; end;
+
+function digit(c: char): integer;
+ begin digit:=ord(c)-ord('0'); end;
+
+function equalsIgnoreCase(s1, s2: string): boolean;
+begin toUpper(s1); toUpper(s2); equalsIgnoreCase:=s1=s2;
+end;
+
+function startsWithIgnoreCase(s1, s2: string): boolean;
+begin toUpper(s1); toUpper(s2); startsWithIgnoreCase:=startsWith(s1,s2);
+end;
+
+function startsWithBracedWord (P: string): boolean;
+ var w: string;
+begin w := getNextWord(P,blank,dummy);
+ startsWithBracedWord := (w[1]='{') and (w[length(w)]='}');
+end;
+
+procedure trim(var s: string);
+ var k: integer;
+ begin k:=posnot(blank,s);
+ if k>1 then predelete(s,k-1) else if k=0 then s:='';
+ end;
+
+function endsWith(s1, s2: string): boolean;
+ var l1, l2: integer;
+begin l1:=length(s1); l2:=length(s2);
+ if l1<l2 then begin endsWith:=false; exit end;
+ predelete(s1,l1-l2); endsWith:=s1=s2
+end;
+
+{--- Match/Replace package --- }
+
+{ Search and replace. Stops when pattern no longer matches source.
+ Pattern wildcards:
+ ? Any single character
+ * Any string
+ # An unsigned integer
+ ## A signed integer
+ ### A signed number maybe with a decimal part
+ Pattern metacharacters:
+ \x where x is any character, stands for that character
+ Target wildcards
+ \0 to \9 Value of corresponding source wildcard
+ Target metacharacters
+ \ When not followed by 0..9 or \, stands for itself
+ \\ Backslash
+}
+procedure grep(var source, pattern, target: string);
+ var p1, p2: array[0..9] of integer;
+ i, j, p, s, t, index, reg: integer;
+ product: string;
+ trigger, matching: boolean;
+ procedure remember(s1, s2: integer);
+ begin if index>9 then halt(9999);
+ p1[index] := s1; p2[index] := s2; s := s2+1; inc(index)
+ end;
+ procedure matchnum;
+ var allowsign, allowpoint, quit: boolean;
+ s0: integer;
+ begin allowsign := false; allowpoint := false; matching := false; s0 := s;
+ if p<length(pattern) then if pattern[p+1]='#' then
+ begin inc(p); allowsign := true;
+ if p<length(pattern) then if pattern[p+1]='#' then
+ begin inc(p); allowpoint := true end
+ end;
+ if allowsign and ((source[s]='-') or (source[s]='+')) then
+ begin inc(s); if s>length(source) then exit end;
+ quit := false;
+ while (not quit) and (s<=length(source)) do
+ begin if source[s]='.' then if not allowpoint then quit := true else
+ begin inc(s); allowpoint := false end;
+ if (source[i]>='0') and (source[i]<='9') then
+ begin inc(s); matching := true end
+ else quit := true
+ end;
+ if matching then remember(s0,s-1)
+ end;
+ procedure matchmeta;
+ begin if p<length(pattern) then inc(p);
+ if source[s]=pattern[p] then begin inc(s); inc(p) end
+ else matching := false
+ end;
+ procedure subgrep;
+ begin matching := true;
+ if pattern[p]='*' then begin remember(s,length(source)); inc(p) end
+ else if pattern[p]='?' then begin remember(s,s); inc(p) end
+ else if pattern[p]='#' then matchnum
+ else if pattern[p]='\' then matchmeta
+ else if source[s]=pattern[p] then begin inc(s); inc(p) end
+ else matching := false
+ end;
+begin
+ index := 0; s := 1; p := 1;
+ for i:=0 to 9 do begin p1[i]:=1; p2[i]:=0 end;
+ while matching and (p<=length(pattern)) and (s<=length(source)) do subgrep;
+ product := ''; trigger := false;
+ for t:=1 to length(target) do if trigger then
+ begin reg := digit(target[t]); if (reg>=0) and (reg<=9) then
+ for j:=p1[reg] to p2[reg] do product := product + source[j]
+ else if target[t]='\' then product := product + '\'
+ else product := product + '\' + target[t];
+ trigger := false
+ end
+ else if (target[t]='\') and (t<length(target)) then trigger := true
+ else product := product + target[t];
+ source := substr(source,s,length(source));
+ pattern := substr(pattern,p,length(pattern));
+ target := product
+end;
+
+
+{ "match" tests whether the source matches the pattern exactly }
+function match(source, pattern: string): boolean;
+ const target: string = '';
+begin grep(source, pattern, target);
+ match := (source='') and (pattern='')
+end;
+
+{ "translate" replaces the pattern by the target in the source. }
+function translate(source, pattern, target: string): string;
+begin grep(source, pattern, target); translate := target;
+end;
+
+end.