annotate lib/ur/string.ur @ 1432:7d024767b024

Cope with DOS-format line breaks in source code
author Adam Chlipala <adam@chlipala.net>
date Thu, 10 Mar 2011 19:26:35 -0500
parents 65fbb250b875
children 2da693675de9
rev   line source
adamc@821 1 type t = Basis.string
adamc@821 2
adamc@1023 3 val str = Basis.str1
adamc@1023 4
adamc@828 5 val length = Basis.strlen
adam@1388 6 val lengthGe = Basis.strlenGe
adamc@828 7 val append = Basis.strcat
adamc@828 8
adamc@821 9 val sub = Basis.strsub
adamc@821 10 val suffix = Basis.strsuffix
adamc@829 11
adamc@829 12 val index = Basis.strindex
adam@1390 13 fun sindex r = Basis.strsindex r.Haystack r.Needle
adamc@829 14 val atFirst = Basis.strchr
adamc@829 15
adamc@1272 16 fun mindex {Haystack = s, Needle = chs} =
adamc@1272 17 let
adamc@1272 18 val n = Basis.strcspn s chs
adamc@1272 19 in
adamc@1272 20 if n >= length s then
adamc@1272 21 None
adamc@1272 22 else
adamc@1272 23 Some n
adamc@1272 24 end
adamc@831 25
adamc@829 26 fun substring s {Start = start, Len = len} = Basis.substring s start len
adamc@829 27
adam@1389 28 fun seek s ch =
adam@1389 29 case index s ch of
adam@1389 30 None => None
adam@1389 31 | Some i => Some (suffix s (i + 1))
adam@1389 32 fun mseek {Haystack = s, Needle = chs} =
adam@1389 33 case mindex {Haystack = s, Needle = chs} of
adam@1389 34 None => None
adam@1389 35 | Some i => Some (sub s i, suffix s (i + 1))
adam@1389 36
adamc@829 37 fun split s ch =
adamc@829 38 case index s ch of
adamc@829 39 None => None
adamc@829 40 | Some i => Some (substring s {Start = 0, Len = i},
adam@1389 41 suffix s (i + 1))
adam@1389 42 fun split' s ch =
adam@1389 43 case index s ch of
adam@1389 44 None => None
adam@1389 45 | Some i => Some (substring s {Start = 0, Len = i},
adam@1389 46 suffix s i)
adamc@831 47 fun msplit {Haystack = s, Needle = chs} =
adamc@831 48 case mindex {Haystack = s, Needle = chs} of
adamc@831 49 None => None
adamc@831 50 | Some i => Some (substring s {Start = 0, Len = i},
adamc@831 51 sub s i,
adam@1389 52 suffix s (i + 1))
adamc@1057 53
adam@1390 54 fun ssplit r =
adam@1390 55 case sindex r of
adam@1390 56 None => None
adam@1390 57 | Some i => Some (substring r.Haystack {Start = 0, Len = i},
adam@1390 58 suffix r.Haystack (i + length r.Needle))
adam@1390 59
adamc@1057 60 fun all f s =
adamc@1057 61 let
adamc@1057 62 val len = length s
adamc@1057 63
adamc@1057 64 fun al i =
adamc@1057 65 i >= len
adamc@1057 66 || (f (sub s i) && al (i + 1))
adamc@1057 67 in
adamc@1057 68 al 0
adamc@1057 69 end
adamc@1122 70
adamc@1131 71 fun mp f s =
adamc@1131 72 let
adamc@1131 73 fun mp' i acc =
adamc@1131 74 if i < 0 then
adamc@1131 75 acc
adamc@1131 76 else
adamc@1131 77 mp' (i - 1) (str (f (sub s i)) ^ acc)
adamc@1131 78 in
adamc@1131 79 mp' (length s - 1) ""
adamc@1131 80 end
adamc@1131 81
adam@1304 82 fun newlines [ctx] [[Body] ~ ctx] (s : string) : xml ([Body] ++ ctx) [] [] =
adamc@1122 83 case split s #"\n" of
adamc@1122 84 None => cdata s
adamc@1122 85 | Some (s1, s2) => <xml>{[s1]}<br/>{newlines s2}</xml>
adamc@1174 86
adamc@1174 87 fun isPrefix {Full = f, Prefix = p} =
adamc@1174 88 length f >= length p && substring f {Start = 0, Len = length p} = p