pads-haskell 0.0.0.1 → 0.1.0.0
raw patch · 106 files changed
+14907/−10337 lines, 106 filesdep +ghc-primdep +mwc-randomdep +pads-haskelldep −Cabaldep −Globdep −directorydep ~HUnitdep ~QuickCheckdep ~basebinary-addedPVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-prim, mwc-random, pads-haskell
Dependencies removed: Cabal, Glob, directory, haskell-src, normaldistribution, old-locale
Dependency ranges changed: HUnit, QuickCheck, base, byteorder, bytestring, containers, haskell-src-meta, mainland-pretty, mtl, parsec, regex-posix, syb, template-haskell, test-framework, test-framework-hunit, test-framework-quickcheck2, th-lift, time, transformers
API changes (from Hackage documentation)
Files
- ChangeLog.md +14/−0
- Documentation/Info/Pads-grammar.tex +6/−4
- Examples/AI.hs +0/−91
- Examples/Binary.hs +0/−74
- Examples/First.hs +0/−992
- Examples/FirstPads.hs +0/−8
- Examples/Proc.hs +0/−51
- Examples/data/README +0/−24
- Examples/data/a2b.c +0/−34
- Examples/data/ai.3000 +0/−3001
- Examples/data/ai.big too large to diff
- Examples/data/binTest.a +0/−1
- Examples/data/binTest.b binary
- Examples/data/binary +0/−1
- Examples/data/calls10.a +0/−11
- Examples/data/calls10.b binary
- Examples/data/genBin.c +0/−40
- Examples/data/test_file +0/−3
- Language/Pads/BaseTypes.hs +0/−155
- Language/Pads/CodeGen.hs +0/−1227
- Language/Pads/CoreBaseTypes.hs +0/−983
- Language/Pads/Errors.hs +0/−77
- Language/Pads/GenPretty.hs +0/−267
- Language/Pads/Generic.hs +0/−203
- Language/Pads/Library/BigEndian.hs +0/−63
- Language/Pads/Library/BinaryUtilities.hs +0/−114
- Language/Pads/Library/LittleEndian.hs +0/−64
- Language/Pads/Library/Native.hs +0/−78
- Language/Pads/MetaData.hs +0/−136
- Language/Pads/PadsParser.hs +0/−534
- Language/Pads/PadsPrinter.hs +0/−123
- Language/Pads/Padsc.hs +0/−59
- Language/Pads/Parser.hs +0/−439
- Language/Pads/Pretty.hs +0/−173
- Language/Pads/Quote.hs +0/−67
- Language/Pads/RegExp.hs +0/−20
- Language/Pads/Source.hs +0/−566
- Language/Pads/Syntax.hs +0/−191
- Language/Pads/TH.hs +0/−164
- Language/Pads/Testing.hs +0/−33
- README.md +71/−0
- Test/Examples.hs +0/−77
- Test/data/maps0 +0/−33
- examples/AI.hs +91/−0
- examples/Addrs.hs +32/−0
- examples/All.hs +16/−0
- examples/Arith.hs +81/−0
- examples/Binary.hs +74/−0
- examples/DFA.hs +62/−0
- examples/DFAC.hs +87/−0
- examples/DOS.hs +15/−0
- examples/First.hs +992/−0
- examples/FirstPads.hs +8/−0
- examples/FullPCAP.hs +278/−0
- examples/HPROF.hs +101/−0
- examples/HmmPlusOrig.hs +119/−0
- examples/IntPair.hs +64/−0
- examples/Main.hs +77/−0
- examples/One.hs +27/−0
- examples/PCAPBodyFill.hs +202/−0
- examples/PCAPBodyGen.hs +192/−0
- examples/Pnm.hs +49/−0
- examples/Proc.hs +51/−0
- examples/Regression.hs +336/−0
- examples/Small.hs +33/−0
- examples/VCard.hs +341/−0
- examples/VCardInfinite.hs +327/−0
- examples/data/README +24/−0
- examples/data/a2b.c +34/−0
- examples/data/ai.3000 +3001/−0
- examples/data/ai.big too large to diff
- examples/data/binTest.a +1/−0
- examples/data/binTest.b binary
- examples/data/binary +1/−0
- examples/data/calls10.a +11/−0
- examples/data/calls10.b binary
- examples/data/genBin.c +40/−0
- examples/data/maps0 +33/−0
- examples/data/test_file +3/−0
- examples/gen-testing/Main.hs +991/−0
- extended/Extensible.hs +60/−0
- extended/Main.hs +19/−0
- pads-haskell.cabal +200/−156
- src/Language/Pads/BaseTypes.hs +158/−0
- src/Language/Pads/CodeGen.hs +1713/−0
- src/Language/Pads/CoreBaseTypes.hs +1298/−0
- src/Language/Pads/Errors.hs +77/−0
- src/Language/Pads/GenPretty.hs +267/−0
- src/Language/Pads/Generation.hs +139/−0
- src/Language/Pads/Generic.hs +203/−0
- src/Language/Pads/Library/BigEndian.hs +84/−0
- src/Language/Pads/Library/BinaryUtilities.hs +114/−0
- src/Language/Pads/Library/LittleEndian.hs +86/−0
- src/Language/Pads/Library/Native.hs +78/−0
- src/Language/Pads/MetaData.hs +136/−0
- src/Language/Pads/PadsParser.hs +534/−0
- src/Language/Pads/PadsPrinter.hs +122/−0
- src/Language/Pads/Padsc.hs +62/−0
- src/Language/Pads/Parser.hs +447/−0
- src/Language/Pads/Pretty.hs +173/−0
- src/Language/Pads/Quote.hs +81/−0
- src/Language/Pads/RegExp.hs +20/−0
- src/Language/Pads/Source.hs +566/−0
- src/Language/Pads/Syntax.hs +189/−0
- src/Language/Pads/TH.hs +163/−0
- src/Language/Pads/Testing.hs +33/−0
@@ -0,0 +1,14 @@+# Changelog for pads-haskell++## Unreleased changes++April 6, 2018:++* Removed type signature generation on Pads Tuple types (missing `Data`+ instance).+* Use [MWC](https://github.com/bos/mwc-random) instead of+ [normaldistribution](https://github.com/bjornbm/normaldistribution) (more+ recent, appears to have more frequent support).+* Lower case source directories and consolidated example files.+* Cabal-build based on an hpack package.yaml file.+
@@ -31,7 +31,7 @@ <constrain> ::= "constrain" <haskell-pat> "::" <ptype> <predic> -<obtain> ::= "obtain" <ptype> "from" <ptype> "using" <expression>+<obtain> ::= "obtain" <ptype> "from" <ptype> "using" <expression> <gen>? <partition> ::= "partition" <ptype> "using" <expression> @@ -65,9 +65,9 @@ <record> ::= "{" <field> ("," <field>)* "}" -<field> ::= <lower> "::" <ftype> <predic>? - \alt <lower> "=" "value" <expression> "::" <ftype> <predic>?- \alt <ftype> <predic>?+<field> ::= <lower> "::" <ftype> <predic>? <gen>?+ \alt <lower> "=" "value" <expression> "::" <ftype> <predic>? <gen>?+ \alt <ftype> <predic>? <gen>? <ftype> ::= "!" <atype> | <ptype> @@ -80,6 +80,8 @@ <literal> ::= <charLit> | <reLit> | <stringLit> | <intLit> | <qualLower> | <qualUpper> <predic> ::= "where" <expression>++<gen> ::= "generator" <expression> <expression> ::= <h-exp> | <literal>
@@ -1,91 +0,0 @@-{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable- , MultiParamTypeClasses- , TypeSynonymInstances- , TemplateHaskell- , QuasiQuotes- , FlexibleInstances #-}---- :set -ddump-splices--module Examples.AI where-import Language.Pads.Padsc-import Language.Pads.GenPretty--import System.IO.Unsafe (unsafePerformIO)---[pads|- newtype AI = AI ([Line Entry] terminator EOF)-- data Entry = Entry- { host :: Src,- ' ', identdID :: ID,- ' ', httpID :: ID,- ' ', time :: TimeStamp,- ' ', request :: Request,- ' ', response :: Response,- ' ', contentLen :: ContentLength }-- data Src = Addr- { a :: IPInt, '.'- , b :: IPInt, '.'- , c :: IPInt, '.'- , d :: IPInt- }- | Name Host- --type IP_v4 = (IPInt, '.', IPInt, '.', IPInt, '.', IPInt)- type IPInt = constrain i :: Int where <| 0 <= i && i < 256 |>- type Host = StringC ' '-- data ID = Missing '-' | Id (StringC ' ')---- type TimeStamp = ('[', Date, ']')- type Date = DateFC <|("%d/%h/%Y:%H:%M:%S %z", ']')|>-- data Request = Request- { '"', method :: Method,- ' ', url :: StringC ' ',- ' ', version :: Version where <| checkVersion method version |>, '"'- }-- data Method = GET | PUT | POST | HEAD | DELETE- | LINK | UNLINK -- obsolete after http 1.0- data Version = Version {"HTTP/", major :: Int, '.', minor :: Int} -- add constriants on major and minor mode-- type Response = constrain r :: Int where <| 100 <= r && r < 600 |>-- data ContentLength = NotAvailable '-' | ContentLength Int- |]--checkVersion :: Method -> Version -> Bool-checkVersion method version =- case method of- LINK -> major version == 1 && minor version == 0- UNLINK -> major version == 1 && minor version == 0- _ -> True----mkPrettyInstance ''AI-mkPrettyInstance ''AI_md--ai_file = ai_big-ai_3000 = "Examples/data/ai.3000"-ai_big = "Examples/data/ai.big"---- (ai_rep, ai_md) = let (AI rep, md) = unsafePerformIO $ parseFile ai_file in (rep,md)-(AI ai_rep, ai_md) = unsafePerformIO $ parseFileWith aI_parseM ai_file---ai_file_length = Prelude.length ai_rep-ai_file_take n = Prelude.take n ai_rep-test = ai_file_take 20--printAI n = putStrLn(pretty 100 (ppr (ai_file_take n)))--result n = do- { (AI rep, md) <- parseFile ai_file- ; return (Prelude.take n rep)- }
@@ -1,74 +0,0 @@-{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables #-}-module Examples.Binary where-import Language.Pads.Padsc-import Language.Pads.Library.LittleEndian as LE-import qualified Language.Pads.Library.BigEndian as BE-import qualified Language.Pads.Library.Native as Native-import Language.Pads.Testing-import System.IO.Unsafe (unsafePerformIO)--test = runTestTT $ TestList tests--tests = [TestLabel "Calls" call_test- ,TestLabel "Calls" callNoRec_test- ,TestLabel "BaseTypes" testRec_test]---[pads| data Call = Call- { onpa :: Int32, obase :: LE.Int32- , dpna :: Int32, dbase :: Int32- , con :: Int32- , dur :: Int32 }-- type Calls = [Call | EOR] terminator EOF- type CallsB = partition Calls using <| bytes 24 |>-- type CallsNoRec = [Call] terminator EOF- type CallsNoRecInstall = partition CallsNoRec using none-|]--call_input_file = "data/calls10.b"-call_result :: (Calls, Calls_md) = unsafePerformIO $ parseFileWith callsB_parseM call_input_file-call_expect = ([Call {onpa = 221, obase = 2360199, dpna = 936, dbase = 3615299, con = 96977709, dur = 71},Call {onpa = 221, obase = 2360399, dpna = 855, dbase = 5445599, con = 96978527, dur = 126},Call {onpa = 221, obase = 2390199, dpna = 974, dbase = 4298199, con = 96980122, dur = 990},Call {onpa = 221, obase = 2390399, dpna = 855, dbase = 5404599, con = 96976885, dur = 35},Call {onpa = 222, obase = 2332099, dpna = 426, dbase = 6814599, con = 96977173, dur = 4850},Call {onpa = 222, obase = 2332099, dpna = -15, dbase = 9999999, con = 96978457, dur = 533},Call {onpa = 222, obase = 2340599, dpna = 855, dbase = 8442799, con = 96980047, dur = 8},Call {onpa = 222, obase = 2341299, dpna = 855, dbase = 7081599, con = 96979104, dur = 11},Call {onpa = 223, obase = 2340099, dpna = 855, dbase = 2484499, con = 96977739, dur = 564},Call {onpa = 223, obase = 2340199, dpna = -15, dbase = 9999999, con = 96979345, dur = 143}],0)-call_test = mkFileTestCase "Call" call_expect call_result--callNoRec_result = unsafePerformIO $ parseFileWith callsNoRecInstall_parseM call_input_file-callNoRec_test = mkFileTestCase "CallNoRec" call_expect callNoRec_result--binary_input_file = "data/binary"-word32sbh_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith BE.word32_parseM binary_input_file-word32sbh_expect = (2864434397,0 )--word32sbl_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith LE.word32_parseM binary_input_file-word32sbl_expect = (3721182122,0)--{- on a little endian machine -}-word32_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith Native.word32_parseM binary_input_file-word32_expect = (3721182122,0)---int32sbh_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith BE.int32_parseM binary_input_file-int32sbh_expect = (-1430532899,0)--int32sbl_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith LE.int32_parseM binary_input_file-int32sbl_expect = (-573785174,0 )--{- on a little endian machine -}-int32_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith Native.int32_parseM binary_input_file-int32_expect = (-573785174,0 )---[pads| data TestRec = TestRec- { w8 :: Word8- , i8 :: Int8- , w16 :: Word16- , i16 :: Int16- , j16 :: Int16- , w32 :: Word32- , i32 :: Int32- } |]--testRec_input_file = "data/binTest.b"-testRec_result :: (TestRec, TestRec_md) = unsafePerformIO $ parseFileWith testRec_parseM testRec_input_file-testRec_expect = (TestRec {w8 = 25, i8 = 23, w16 = 300, i16 = -400, j16 = 899, w32 = 9876, i32 = -98744},0)-testRec_test = mkFileTestCase "BinaryBaseTypes" testRec_expect testRec_result
@@ -1,992 +0,0 @@-{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,- MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,- DeriveDataTypeable, ScopedTypeVariables #-}--module Examples.First where-import Language.Pads.Padsc-import Language.Pads.Testing-import Examples.FirstPads-import Language.Haskell.TH--import System.IO.Unsafe (unsafePerformIO)-import Data.Char as Char-import qualified Data.ByteString as B-import Data.Word----import qualified Text.Regex.ByteString as BRE--ws = REd "[\t ]+|$" " "------ PADS EXAMPLES--[pads| |]--[pads| type MyChar = Char |]-myChar_result = myChar_parseS "ab"-myChar_expects = ('a', 0,"b")-myChar_test = mkTestCase "myChar" myChar_expects myChar_result--[pads| type IntPair = (Int, '|', Int) |]-intPair_result = intPair_parseS "12|23"-intPair_expects = ((12,23), 0,"")-intPair_test = mkTestCase "intPair" intPair_expects intPair_result--[pads| type Bar = (Int, ',', IntPair, ';', Int) |] -- reference to another named type-bar_result = bar_parseS "256,12|23;456:"-bar_expects = ((256, (12, 23), 456), 0, ":")-bar_test = mkTestCase "bar" bar_expects bar_result--[pads| type Bar2 = (Int, ',', (Int,':',Int), ';', Int) |] -- nested tuple type.-bar2_result = bar2_parseS "56,23:46;29"-bar2_expects = ((56,(23,46),29), 0 ,"")-bar2_test = mkTestCase "bar2" bar2_expects bar2_result--[pads| type BazR = Line (Int, ',', Int) |] -- type that consumes a line boundary.-bazr_result = bazR_parseS "33,33\n"-bazr_expects = ((33,33),0,"")-bazr_test = mkTestCase "bazr" bazr_expects bazr_result--[pads| type MyInt = Int |] -- Integer base type-myInt_result = myInt_parseS "23"-myInt_expects = (23,0,"")-myInt_test = mkTestCase "myInt" myInt_expects myInt_result---{- String base types -}-testStrLen = 2-computeLen x = x - 1-[pads| type StrTy = StringFW <| testStrLen + (computeLen 4) |> |]-inputStrTy = "catdog"-strTy_results = strTy_parseS inputStrTy-strTy_expects = ("catdo", 0,"g")-strTy_test = mkTestCase "strTy" strTy_expects strTy_results--[pads| type StrTy1 = StringC 'o' |]-strTy1_results = strTy1_parseS inputStrTy-strTy1_expects = ("catd",0,"og")-strTy1_test = mkTestCase "strTy1" strTy1_expects strTy1_results--[pads| type Baz = (StringFW 3,',',Int) |]-input_baz = "cat,123"-baz_results = baz_parseS input_baz-baz_expects = (("cat",123),0,"")-baz_test = mkTestCase "baz" baz_expects baz_results--{- Regular expression types -}-[pads| type StrME = StringME 'a+' |]-input_strME = "aaaab"-strME_results = strME_parseS input_strME--[pads| type StrSE = StringSE <|RE "b|c"|> |]-input_strSE_1 = "aaaab"-input_strSE_2 = "aaaac"-strSE_results_1 = strSE_parseS input_strSE_1-strSE_results_2 = strSE_parseS input_strSE_2--[pads| type StrP1 (x::Int) = StringFW <|x - 1|> |]-input_strP1 = "abcd"-strP1_result = strP1_parseS 3 input_strP1--[pads| type StrHex = StringME '[0-9A-Fa-f]+' |]-input_strHex = "12abcds"-strHex_result = strHex_parseS input_strHex--{- Testing for Phex32FW, which is in Pads.Language.BaseTypes -}-input_hex32FW = "12bc34"-phex32FW_results = phex32FW_parseS 4 input_hex32FW-phex32FW_expects = (4796, 0, "34")-phex32FW_test = mkTestCase "phex32FW" phex32FW_expects phex32FW_results--input2_hex32FW = "00bc34"-strhex32FW_result2 = phex32FW_parseS 4 input2_hex32FW -- ((Phex32FW (188),Errors: 0),"34")--input3_hex32FW = "gbc34"-strhex32FW_result3 = phex32FW_parseS 4 input3_hex32FW -- Prints error message--[pads| type HexPair = (Phex32FW 2, ',', Phex32FW 3) |]-input_hexpair = "aa,bbb"-hexpair_result = hexPair_parseS input_hexpair---{- Constrained types -}-[pads| type IntRange = constrain x :: Int where <| 0 <= x && x <= 256 |> |]-intRange24_input = "24"-intRange0_input = "0"-intRange256_input = "256"-intRangeLow_input = "-23"-intRangeHigh_input = "512"-intRangeBad_input = "aaa"--result_intRange24 = intRange_parseS intRange24_input-expect_intRange24 = (24,0,"")-test_intRange24 = mkTestCase "IntRange24" expect_intRange24 result_intRange24--result_intRange0 = intRange_parseS intRange0_input-expect_intRange0 = (0,0,"")-test_intRange0 = mkTestCase "IntRange0" expect_intRange0 result_intRange0--result_intRange256 = intRange_parseS intRange256_input-expect_intRange256 = (256,0,"")-test_intRange256 = mkTestCase "IntRange256" expect_intRange256 result_intRange256--result_intRangeLow = intRange_parseS intRangeLow_input-expect_intRangeLow = ((-23),1,"")-test_intRangeLow = mkTestCase "IntRangeLow" expect_intRangeLow result_intRangeLow--result_intRangeHigh = intRange_parseS intRangeHigh_input-expect_intRangeHigh = (512,1,"")-test_intRangeHigh = mkTestCase "IntRangeHigh" expect_intRangeHigh result_intRangeHigh--result_intRangeBad = intRange_parseS intRangeBad_input-expect_intRangeBad = (0,1,"aaa")-test_intRangeBad = mkTestCase "IntRangeBad" expect_intRangeBad result_intRangeBad--{- Note that the special variable "md" is in scope in the body of the predicate. -}-{- md is the meta-data descriptor for the underyling type. -}--[pads| type IntRangeP (low::Int, high::Int) = constrain x :: Int where <| low <= x && x <= high && (numErrors md == 0) |> |]--result_intRangeP24 = intRangeP_parseS (0, 256) intRange24_input-expect_intRangeP24 = (24,0,"")-test_intRangeP24 = mkTestCase "IntRangeP24" expect_intRangeP24 result_intRangeP24--result_intRangeP0 = intRangeP_parseS (0, 256) intRange0_input-expect_intRangeP0 = (0,0,"")-test_intRangeP0 = mkTestCase "IntRangeP0" expect_intRangeP0 result_intRangeP0--result_intRangeP256 = intRangeP_parseS (0, 256) intRange256_input-expect_intRangeP256 = (256,0,"")-test_intRangeP256 = mkTestCase "IntRangeP256" expect_intRangeP256 result_intRangeP256--result_intRangePLow = intRangeP_parseS (0, 256) intRangeLow_input-expect_intRangePLow = ((-23), 1, "")-test_intRangePLow = mkTestCase "IntRangePLow" expect_intRangePLow result_intRangePLow---result_intRangePHigh = intRangeP_parseS (0, 256) intRangeHigh_input-expect_intRangePHigh = (512, 1,"")-test_intRangePHigh = mkTestCase "IntRangePHigh" expect_intRangePHigh result_intRangePHigh---result_intRangePBad = intRangeP_parseS (0, 256) intRangeBad_input-expect_intRangePBad = (0, 2,"aaa")-test_intRangePBad = mkTestCase "IntRangePBad" expect_intRangePBad result_intRangePBad-----[pads| data Record (bound::Int) = Record- { i1 :: Int,- ',', i2 :: Int where <| i1 + i2 <= bound |> } |]--input_Record = "24,45"-result_Record = record_parseS 100 input_Record-expect_Record = (Record {i1 = 24, i2 = 45},0,"")-test_Record = mkTestCase "Record" expect_Record result_Record--[pads| data Id = Numeric Int- | Alpha (StringC ',') |]--input_IdInt = "23"-result_IdInt = id_parseS input_IdInt-expect_IdInt = (Numeric 23,0,"")-test_IdInt = mkTestCase "IdInt" expect_IdInt result_IdInt--input_IdStr = "hello"-result_IdStr = id_parseS input_IdStr-expect_IdStr = (Alpha ("hello"),0,"")-test_IdStr = mkTestCase "IdAlpha" expect_IdStr result_IdStr--[pads| data Id2 (bound::Int) =- Numeric2 (constrain n::Int where <| n <= bound |>)- | Alpha2 (StringC ',') |]-input_IdInt2 = "23"-result_IdInt2 = id2_parseS 10 input_IdInt2-expect_IdInt2 = (Alpha2 ("23"),0,"")-test_IdInt2 = mkTestCase "IdInt2" expect_IdInt2 result_IdInt2--input_IdStr2 = "hello"-result_IdStr2 = id2_parseS 10 input_IdStr2-expect_IdStr2 = (Alpha2 ("hello"),0,"")-test_IdStr2 = mkTestCase "IdAlpha2" expect_IdStr2 result_IdStr2----[pads| data Id3 = Numeric3 (IntRangeP <|(1,10)|>)- | Numeric3a Int- | Lit3 ',' |]-input_IdInt3 = "24"-result_IdInt3 = id3_parseS input_IdInt3-expect_IdInt3 = (Numeric3a (24),0,"")-test_IdInt3 = mkTestCase "IdInt3" expect_IdInt2 result_IdInt2--input_IdLit3 = ","-result_IdLit3 = id3_parseS input_IdLit3-expect_IdLit3 = (Lit3,0,"")-test_IdLit3 = mkTestCase "IdLit3" expect_IdLit3 result_IdLit3----[pads| data Ab_or_a = AB "ab" | A "a" |]-input_AB = "ab"-result_Ab_or_a = ab_or_a_parseS input_AB-expect_Ab_or_a = (AB,0,"")-test_Ab_or_a = mkTestCase "Ab_or_a" expect_Ab_or_a result_Ab_or_a--[pads| data AB_test = AB_test { field_AB :: Ab_or_a , 'b'} |]-input_AB_test1 = "abb"-result_AB_test1 = aB_test_parseS input_AB_test1-expect_AB_test1 = (AB_test {field_AB = AB},0,"")-test_AB_test1 = mkTestCase "AB_test1" expect_AB_test1 result_AB_test1--input_AB_test2 = "ab"-result_AB_test2 = aB_test_parseS input_AB_test2---expect_AB_test2 = (AB_test {field_AB = A},0,"") -- if backtracking-expect_AB_test2 = (AB_test {field_AB = AB},1,"")-test_AB_test2 = mkTestCase "AB_test2" expect_AB_test2 result_AB_test2--[pads| data Method = GET | PUT | LINK | UNLINK | POST- data Version = Version- {"HTTP/"- , major :: Int, '.'- , minor :: Int}-|]--checkVersion :: Method -> Version -> Bool-checkVersion method version =- case method of- LINK -> major version == 1 && minor version == 0- UNLINK -> major version == 1 && minor version == 0- _ -> True--[pads| data Request = Request- { '"', method :: Method- , ' ', url :: StringC ' '- , ' ', version :: Version where <| checkVersion method version |>- , '"'- } |]--input_method_get = "GET"-result_method_get = method_parseS input_method_get-expect_method_get = (GET,0,"")-test_method_get = mkTestCase "Method_get" expect_method_get result_method_get--input_method_put = "PUT"-result_method_put = method_parseS input_method_put-expect_method_put = (PUT,0,"")-test_method_put = mkTestCase "Method_put" expect_method_put result_method_put---input_method_link = "LINK"-result_method_link = method_parseS input_method_link-expect_method_link = (LINK,0,"")-test_method_link = mkTestCase "Method_link" expect_method_link result_method_link---input_method_post = "POST"-result_method_post = method_parseS input_method_post-expect_method_post = (POST,0,"")-test_method_post = mkTestCase "Method_post" expect_method_post result_method_post---input_version = "HTTP/1.2"-result_version = version_parseS input_version-expect_version = (Version {major = 1, minor = 2},0,"")-test_version = mkTestCase "Version" expect_version result_version--input_request_G = "\"PUT /www.google.com HTTP/1.0\""-result_request_G = request_parseS input_request_G-expect_request_G = (Request {method = PUT, url = "/www.google.com", version = Version {major = 1, minor = 0}}, 0, "")-test_request_G = mkTestCase "Request_G" expect_request_G result_request_G--input_request_B = "\"LINK /www.google.com HTTP/1.3\""-result_request_B = request_parseS input_request_B-expect_request_B = (Request {method = LINK, url = "/www.google.com", version = Version {major = 1, minor = 3}},1, "")-test_request_B = mkTestCase "Request_B" expect_request_B result_request_B--[pads| type Eor_Test = (Int, EOR, Int) |]-input_eor_test = "23\n56"-result_eor_test = eor_Test_parseS input_eor_test-expect_eor_test = ((23,56),0,"")-test_eor_test = mkTestCase "Eor_Test" expect_eor_test result_eor_test--[pads| type Eof_Test = (Int, EOR, Int, EOF) |]-input_eof_test_G = "23\n56"-result_eof_test_G = eof_Test_parseS input_eof_test_G-expect_eof_test_G = ((23,56),0,"")-test_eof_test_G = mkTestCase "Eof_TestG" expect_eof_test_G result_eof_test_G--input_eof_test_B = "23\n56ab"-result_eof_test_B = eof_Test_parseS input_eof_test_B-expect_eof_test_B = ((23,56), 1,"ab")-test_eof_test_B = mkTestCase "Eof_TestB" expect_eof_test_B result_eof_test_B--{- Restate after Maybe is implemented -}-[pads| type Opt_test = (Int, '|', Maybe Int, '|', Int) |]-input_opt_test_j = "34|35|56"-result_opt_test_j = opt_test_parseS input_opt_test_j-expect_opt_test_j = ((34,Just 35,56),0,"")-test_opt_test_j = mkTestCase "Opt_test_j" expect_opt_test_j result_opt_test_j--input_opt_test_n = "34||56"-result_opt_test_n = opt_test_parseS input_opt_test_n-expect_opt_test_n = ((34,Nothing,56),0,"")-test_opt_test_n = mkTestCase "Opt_test_n" expect_opt_test_n result_opt_test_n---{- LIST EXAMPLES -}--[pads| type Entries_nosep_noterm = [StringFW 3] |]-input_entries_nosep_noterm = "123456789"-result_entries_nosep_noterm = entries_nosep_noterm_parseS input_entries_nosep_noterm-expect_entries_nosep_noterm = (["123","456","789"],0,"")-test_entries_nosep_noterm = mkTestCase "NoSep_NoTerm" expect_entries_nosep_noterm result_entries_nosep_noterm--input_entries_nosep_noterm' = "1234567890"-result_entries_nosep_noterm' = entries_nosep_noterm_parseS input_entries_nosep_noterm'-expect_entries_nosep_noterm' = (["123","456","789"],0,"0")-test_entries_nosep_noterm' = mkTestCase "NoSep_NoTerm'" expect_entries_nosep_noterm' result_entries_nosep_noterm'--[pads| type Entries_nosep_noterm2 = [Char] |]-input_entries_nosep_noterm2 = ""-result_entries_nosep_noterm2 = entries_nosep_noterm2_parseS input_entries_nosep_noterm2-expect_entries_nosep_noterm2 = ([],0,"")-test_entries_nosep_noterm2 = mkTestCase "NoSep_NoTerm2" expect_entries_nosep_noterm2 result_entries_nosep_noterm2---[pads| type EvenInt = constrain x :: Digit where <| x `mod` 2 == 0 |>- type EvenInts = [EvenInt] |]-input_evenInts = "2465"-result_evenInt = evenInt_parseS input_evenInts-expect_evenInt = ( 2,0,"465")-test_evenInt = mkTestCase "EvenInt" expect_evenInt result_evenInt--result_evenInts = evenInts_parseS input_evenInts-expect_evenInts = ([2,4,6],0,"5")-test_evenInts = mkTestCase "EvenInts" expect_evenInts result_evenInts---[pads| type DigitList = [Digit | ','] |]-input_digitListG = "1,2,3"-input_digitList2G = "1,2,3|fed"-input_digitListB = "1,b,3"-result_digitListG = digitList_parseS input_digitListG-expect_digitListG = ([1,2,3],0,"")-test_digitListG = mkTestCase "DigitListG" expect_digitListG result_digitListG--result_digitList2G = digitList_parseS input_digitList2G-expect_digitList2G = ([1,2,3],0,"|fed")-test_digitList2G = mkTestCase "DigitList2G" expect_digitList2G result_digitList2G--result_digitListB = digitList_parseS input_digitListB-expect_digitListB = ([1],0,",b,3")-test_digitListB = mkTestCase "DigitListB" expect_digitListB result_digitListB--[pads| type DigitListLen (x::Int) = [Digit] length <|x + 1 |> |]-input_digitListLenG = "123456"-input_digitListLenB = "12a456"--result_digitListLenG = digitListLen_parseS 4 input_digitListLenG-expect_digitListLenG = ([1,2,3,4,5],0,"6")-test_digitListLenG = mkTestCase "DigitListLenG" expect_digitListLenG result_digitListLenG--result_digitListLenB = digitListLen_parseS 4 input_digitListLenB-expect_digitListLenB = ([1,2,0,4,5],1 ,"6")-test_digitListLenB = mkTestCase "DigitListLenB" expect_digitListLenB result_digitListLenB---[pads| type DigitListLenSep (x::Int) = [Digit | "ab" ] length <|x + 1|> |]-input_digitListLenSepG = "1ab2ab3ab4ab5ab6ab7ab"-input_digitListLenSepB = "1ab2ab3abDab5ab6ab7ab"-result_digitListLenSepG = digitListLenSep_parseS 4 input_digitListLenSepG-expect_digitListLenSepG = ([1,2,3,4,5],0,"ab6ab7ab")-test_digitListLenSepG = mkTestCase "DigitListLenSepG" expect_digitListLenSepG result_digitListLenSepG--result_digitListLenSepB = digitListLenSep_parseS 4 input_digitListLenSepB-expect_digitListLenSepB = ([1,2,3,0,5],1,"ab6ab7ab")-test_digitListLenSepB = mkTestCase "DigitListLenSepB" expect_digitListLenSepB result_digitListLenSepB---[pads| type DigitListTerm = [Digit] terminator EOR|]-input_digitListTermG = "12345\nhello"-result_digitListTermG = digitListTerm_parseS input_digitListTermG-expect_digitListTermG = ([1,2,3,4,5],0,"hello")-test_digitListTermG = mkTestCase "DigitListTermG" expect_digitListTermG result_digitListTermG--input_digitListTermB = "12345,h"-result_digitListTermB = digitListTerm_parseS input_digitListTermB-expect_digitListTermB = ([1,2,3,4,5,0,0],2,"")-test_digitListTermB = mkTestCase "DigitListTermB" expect_digitListTermB result_digitListTermB--[pads| type DigitListTermSep = [Digit | '|' ] terminator ';' |]-input_digitListTermSepG = "1|2|3|4|5|6;hello"-result_digitListTermSepG = digitListTermSep_parseS input_digitListTermSepG-expect_digitListTermSepG = ([1,2,3,4,5,6], 0,"hello")-test_digitListTermSepG = mkTestCase "digitListTermSepG" expect_digitListTermSepG result_digitListTermSepG--input_digitListTermSepB = "1|2|3|4|56;hello"-result_digitListTermSepB = digitListTermSep_parseS input_digitListTermSepB-expect_digitListTermSepB = ([1,2,3,4,5],1,"hello")-test_digitListTermSepB = mkTestCase "digitListTermSepB" expect_digitListTermSepB result_digitListTermSepB--[pads| type TryTest = (Try Char, StringFW 3) |]-input_tryTest = "abc123"-result_tryTest = tryTest_parseS input_tryTest-expect_tryTest = (('a',"abc"),0,"123")-test_tryTest = mkTestCase "tryTest" expect_tryTest result_tryTest--[pads| type TryTestD = (Try Digit, StringFW 3) |]-input_tryTestDG = "123abc"-result_tryTestDG = tryTestD_parseS input_tryTestDG-expect_tryTestDG = ((1,"123"),0,"abc")-test_tryTestDG = mkTestCase "tryTestDG" expect_tryTestDG result_tryTestDG---- Note that 'try_parseM' does not return an error when it fails to parse a--- digit (and therefore uses the default value of "0") because a "try" parser--- should fail silently, similar to how the 'try' combinator works in parsec.-input_tryTestDB = "abc123"-result_tryTestDB = tryTestD_parseS input_tryTestDB-expect_tryTestDB = ((0,"abc"),0,"123")-test_tryTestDB = mkTestCase "tryTestDB" expect_tryTestDB result_tryTestDB--{- ((TryTestD (0,"abc"),- (Errors: 1 Encountered a when expecting Digit. at: Line: 0, Offset:- 0,(Errors: 1 Encountered a when expecting Digit. at: Line: 0, Offset:- 0,Errors: 0))),"123")-- XXX: we are getting a repeat error message because of change to how errors are- propagated. Need to work on cleaning up error reporting.--}---[pads| type ListWithTry = ([Char] terminator (Try Digit), Digit) |]-input_ListWithTry = "cat123"-result_ListWithTry = listWithTry_parseS input_ListWithTry-expect_ListWithTry = ((['c', 'a', 't'],1),0,"23")-test_ListWithTry = mkTestCase "ListWithTry" expect_ListWithTry result_ListWithTry----[pads| type WithVoid = (Char, ',', Void, '|') |]-input_WithVoid = "a,|rest"-result_WithVoid = withVoid_parseS input_WithVoid-expect_WithVoid = ('a',0,"rest")-test_WithVoid = mkTestCase "WithVoid" expect_WithVoid result_WithVoid--[pads| data VoidOpt = PDigit Digit | Pcolor "red" | Pnothing Void- type VoidEntry = (VoidOpt, StringFW 3) |]-input_voidEntry1 = "9abcdef"-result_voidEntry1 = voidEntry_parseS input_voidEntry1-expect_voidEntry1 = ((PDigit 9,"abc"),0,"def")-test_voidEntry1 = mkTestCase "VoidEntry1" expect_voidEntry1 result_voidEntry1--input_voidEntry2 = "redabcdef"-result_voidEntry2 = voidEntry_parseS input_voidEntry2-expect_voidEntry2 = ((Pcolor,"abc"),0,"def")-test_voidEntry2 = mkTestCase "VoidEntry2" expect_voidEntry2 result_voidEntry2--input_voidEntry3 = "abcdef"-result_voidEntry3 = voidEntry_parseS input_voidEntry3-expect_voidEntry3 = ((Pnothing,"abc"),0,"def")-test_voidEntry3 = mkTestCase "VoidEntry3" expect_voidEntry3 result_voidEntry3--[pads| data Switch (which :: Int) =- case <| which |> of- 0 -> Even Int where <| even `mod` 2 == 0 |>- | 1 -> Comma ','- | otherwise -> Missing Void |]-input_switch0 = "2hello"-input_switch1 = ",hello"-input_switchOther = "hello"--result_switch0 = switch_parseS 0 input_switch0-expect_switch0 = (Even (2),0,"hello")-test_switch0 = mkTestCase "switch0" expect_switch0 result_switch0--result_switch1 = switch_parseS 1 input_switch1-expect_switch1 = (Comma,0,"hello")-test_switch1 = mkTestCase "switch1" expect_switch1 result_switch1--result_switchOther = switch_parseS 2 input_switchOther-expect_switchOther = (Missing,0,"hello")-test_switchOther = mkTestCase "switchOther" expect_switchOther result_switchOther----result_stringln = stringLn_parseS "hello\ngoodbye"-expect_stringln = ("hello",0,"\ngoodbye")-test_stringln = mkTestCase "stringln" expect_stringln result_stringln--[pads| data MyBody (which::Int) =- case <| which |> of- 0 -> First Int- | 1 -> Second (StringC ',')- | otherwise -> Other Void-- data MyEntry = MyEntry- { header :: Int, ','- , body :: MyBody header, ','- , trailer :: Char}-- type MyData = [Line MyEntry] terminator EOF |]--input_myData = "0,23,a\n1,hello,b\n2,,c\n"-result_myData = myData_parseS input_myData-expect_myData = ([MyEntry {header = 0, body = First (23), trailer = 'a'},- MyEntry {header = 1, body = Second ("hello"), trailer = 'b'},- MyEntry {header = 2, body = Other, trailer = 'c'}],0, "")-test_myData = mkTestCase "MyData" expect_myData result_myData----[pads| data HP = HP { student_num :: Int, ',',- student_name :: StringFW student_num }- type HP_data = [Line HP] terminator EOF |]--input_hp_data = "8,Hermione\n3,Ron\n5,Harry\n"-result_hp_data = hP_data_parseS input_hp_data-expect_hp_data = ([HP {student_num = 8, student_name = "Hermione"},- HP {student_num = 3, student_name = "Ron"},- HP {student_num = 5, student_name = "Harry"}], 0, "")-test_hp_data = mkTestCase "HP Data" expect_hp_data result_hp_data----test_file = "Examples/data/test_file"-result_hp_data_file_parse :: (HP_data, HP_data_md) = unsafePerformIO $ parseFileWith hP_data_parseM test_file--expect_hp_data_file_parse =- ( [HP {student_num = 8, student_name = "Hermione"},- HP {student_num = 3, student_name = "Ron"},- HP {student_num = 5, student_name = "Harry"}], 0)-test_hp_data_file_parse = mkFileTestCase "HP file" expect_hp_data_file_parse result_hp_data_file_parse----strToBS = B.pack . (map chrToWord8)--[pads| newtype MyDoc = MyDoc Text |]-myDoc_input_file = "Examples/data/test_file"-myDoc_result :: (MyDoc, MyDoc_md) = unsafePerformIO $ parseFile myDoc_input_file-myDoc_expects = (MyDoc (Text (strToBS "8,Hermione\n3,Ron\n5,Harry\n")),0)-myDoc_test = mkFileTestCase "myDoc" myDoc_expects myDoc_result---acomma = ","-[pads| data LitRec = LitRec { fstField :: Int, acomma, sndField :: Int} |]-litRec_input = "12,34"-litRec_result = litRec_parseS litRec_input-litRec_expects = (LitRec {fstField = 12, sndField = 34},0,"")-litRec_test = mkTestCase "Haskell identifier literal" litRec_expects litRec_result--[pads| type WhiteSpace = (Int, '[ \t]+', Int) |]-whiteSpace_input = "12 34"-whiteSpace_result = whiteSpace_parseS whiteSpace_input-whiteSpace_expects = ((12,34),0,"")-whiteSpace_test = mkTestCase "regular expression literal" whiteSpace_expects whiteSpace_result----[pads| type WhiteSpace2 = (Int, ws, Int) |]-whiteSpace2_input = "12 34"-whiteSpace2_result = whiteSpace2_parseS whiteSpace2_input-whiteSpace2_expects = ((12,34),0,"")-whiteSpace2_test = mkTestCase "Haskell expression regular expression literal" whiteSpace2_expects whiteSpace2_result--[pads| type RE_ty = (StringME '[tod]', ws, StringME 'a+') |]-rE_ty_input = "t aaaa"-rE_ty_result = rE_ty_parseS rE_ty_input-rE_ty_expects = (("t","aaaa"),0,"")-rE_ty_test = mkTestCase "regular expression abbreviation for StringME" rE_ty_expects rE_ty_result---[pads| type Disc = (Int, EOR, Int, EOR, (partition (Int, EOR, Int, EOR) using windows), Int, EOR) |]-disc_input = "1\n2\n3\r\n4\r\n5\n"-disc_result = disc_parseS disc_input-disc_expects = ((1,2,(3,4),5),0,"")-disc_test = mkTestCase "multiple record disciplines" disc_expects disc_result--[pads| data Exxy a = Exxy {exxy :: Int, aa :: a}- type ExxyInt = Exxy Char |]-exxy_input = "32635def"-exxy_result = exxyInt_parseS exxy_input-exxy_expects = (Exxy {exxy = 32635, aa = 'd'},0,"ef")-exxy_test = mkTestCase "label overlap" exxy_expects exxy_result--[pads| type OneLine = [Char] terminator EOR- type Lines = [OneLine] terminator EOF- type LinesFW = partition Lines using <| bytes 3 |>-|]--linesFW_input = "123456789"-linesFW_result = linesFW_parseS linesFW_input-linesFW_expects = (["123","456","789"],0,"")-linesFW_test = mkTestCase "fixed-width record discpline" linesFW_expects linesFW_result---[pads| type Strs = [StringSE ws | ws] terminator EOR |]-strs_input = "0.700264\n"-strs_result = strs_parseS strs_input--[pads| data Vals = Vals { vv :: Int, uu = value <| even vv |> :: Bool, ww::Char} |]-vals_input = "123x"-vals_result = vals_parseS vals_input-vals_expects = (Vals {vv=123,uu=False,ww='x'},0,"")-vals_test = mkTestCase "values" vals_expects vals_result--[pads| data Vals2 = Vals2 { vv2 :: (Int,",",Int),- uu2 = value <| fst vv2 `mod` snd vv2 == 0 |> :: Bool,- ww2 :: Char} |]-vals2_input = "12,3x"-vals2_result = vals2_parseS vals2_input-vals2_expects = (Vals2 {vv2=(12,3),uu2=True,ww2='x'},0,"")-vals2_test = mkTestCase "values" vals2_expects vals2_result---{--[pads| data Vals3 a = Vals3 { vv3 :: (Int,",",Int),- uu3 = value <| [] |> :: [a],- ww3 :: Char} |]-vals3_input = "12,3x"-vals3_result = vals3_parseS vals3_input-vals3_expects = (Vals3 {vv3=(12,3),uu3=[],ww3='x'},0,"")-vals3_test = mkTestCase "values" vals3_expects vals3_result--}--[pads| type Doubles = [Double | EOR] terminator EOF |]-doubles_input = "12.34\n1\n-12.0\n1.3e4\n1.2e-2"-doubles_result = doubles_parseS doubles_input-doubles_expects = ([12.34,1.0,-12.0,13000.0,1.2e-2],0,"")-doubles_test = mkTestCase "doubles" doubles_expects doubles_result--[pads| type StringSEs = [StringSE <|RE "$"|> | EOR] terminator EOF |]--stringSEs_input = "12.34\n1\n-12.0\n1.3e4\n1.2e-2"-stringSEs_result = stringSEs_parseS stringSEs_input-stringSEs_expects = (["12.34","1","-12.0","1.3e4","1.2e-2"],0,"")-stringSEs_test = mkTestCase "stringSEs" stringSEs_expects stringSEs_result--[pads| type StringFWs = [StringFW 3| EOR] terminator EOF |]-stringFWs_input = "abc\nabcd\nab\nabc"-stringFWs_result = stringFWs_parseS stringFWs_input-stringFWs_expects = (["abc","abc","XXX","abc"],2,"")-stringFWs_test = mkTestCase "stringFWs" stringFWs_expects stringFWs_result---[pads| type StringESCs = [(StringESC <| ('!', ";,") |>, '[;,]') | EOR] terminator EOF |]-stringESCs_input = "abc\na;\nb,\na!;bc,\na!,cd\nhe!"-stringESCs_result = stringESCs_parseS stringESCs_input-stringESCs_expects = (["abc","a","b","a;bc","a,cd","he!"],4, "")-stringESCs_test = mkTestCase "stringESCs" stringESCs_expects stringESCs_result--[pads| type StringPs = [StringP Char.isDigit | EOR] terminator EOF |]-stringPs_input = "123\na\n123a"-stringPs_result = stringPs_parseS stringPs_input-stringPs_expects = (["123","","123"],2, "")-stringPs_test = mkTestCase "stringPs" stringPs_expects stringPs_result--{- Bit-level functionality tests -}--[pads| type BitBools = (partition [BitBool] using none) |]-bitBools_input = "a" -- binary 01100001-bitBools_result = bitBools_parseS bitBools_input-bitBools_expects = ([False,True,True,False,False,False,False,True], 0, "")-bitBools_test = mkTestCase "bitBools" bitBools_expects bitBools_result--bitBools_input2 = "a\n" -- binary 01100001 00001010-bitBools_result2 = bitBools_parseS bitBools_input2-bitBools_expects2 = ([False,True,True,False,False,False,False,True,- False,False,False,False,True,False,True,False], 0, "")-bitBools_test2 = mkTestCase "bitBools" bitBools_expects2 bitBools_result2--[pads| type IncompleteBitBools = (partition (BitBool,- BitBool,- BitBool) using none) |]-incompleteBitBools_input = "4"-incompleteBitBools_result = incompleteBitBools_parseS incompleteBitBools_input-incompleteBitBools_expects = ((False,False,True), 0, "4")-incompleteBitBools_test = mkTestCase "incompleteBitBools"- incompleteBitBools_expects- incompleteBitBools_result--[pads| type ArithPixel = (partition (Bits16 9,- Bits8 5,- Bits8 5,- Bits8 5,- Bits8 4,- Bits8 4) using none) |]-arithPixel_input = map word8ToChr [136,114,32,0]-arithPixel_result = arithPixel_parseS arithPixel_input-arithPixel_expects = ((272,28,17,0,0,0), 0, "")-arithPixel_test = mkTestCase "arithPixel" arithPixel_expects arithPixel_result--[pads| type Mixed = (partition (StringC ' ',- ' ',- Bits8 4,- BitBool,- Bits8 3,- Char) using none) |]--mixed_input = "Hello " ++ (map word8ToChr [74]) ++ "c"-mixed_result = mixed_parseS mixed_input-mixed_expects = (("Hello",4,True,2,'c'), 0, "")-mixed_test = mkTestCase "mixed" mixed_expects mixed_result--[pads| type OddWidths = (partition (Bits32 19,- Bits64 39,- Bits8 1,- Bits8 5) using none) |]--oddWidths_input = map word8ToChr [104,46,174,3,185,8,6,158]-oddWidths_result = oddWidths_parseS oddWidths_input-oddWidths_expects = ((213365,240768000026,0,30), 0, "")-oddWidths_test = mkTestCase "oddWidths" oddWidths_expects oddWidths_result--[pads| type LargeWidths = (partition (Bits8 7,- BitField 89,- BitField 65) using none) |]--largeWidths_input = map word8ToChr [1,0,0,0,0,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,128]-largeWidths_result = largeWidths_parseS largeWidths_input-largeWidths_expects = ((0,309485009821345068724781057,18446744073709551617), 0, map word8ToChr [128])-largeWidths_test = mkTestCase "largeWidths" largeWidths_expects largeWidths_result--[pads| data EnumType (x :: Bits8) = case x of 0 -> ZERO {}- | 1 -> ONE {}- | 2 -> TWO {}- | _ -> OTHER {}-- data Enumerate = Enumerate {x :: Bits8 3,- Bits8 5,- y :: EnumType x}-- type Enumerated = (partition Enumerate using none) |]--enumerated_input = map word8ToChr [64]-enumerated_result = enumerated_parseS enumerated_input-enumerated_expects = (Enumerate {x = 2, y = TWO}, 0, "")-enumerated_test = mkTestCase "Enumerated" enumerated_expects enumerated_result--enumerated_input_wc = map word8ToChr [255]-enumerated_result_wc = enumerated_parseS enumerated_input_wc-enumerated_expects_wc = (Enumerate {x = 7, y = OTHER}, 0, "")-enumerated_test_wc = mkTestCase "EnumeratedWC" enumerated_expects_wc enumerated_result_wc--[pads| data EnumTypeBool (x' :: BitBool) = case x' of True -> ON {}- | False -> OFF {}-- data EnumerateBool = EnumerateBool {Bits8 7,- x' :: BitBool,- y' :: EnumTypeBool x'}-- type EnumeratedBool = (partition EnumerateBool using none) |]--enumeratedBool_input = map word8ToChr [1]-enumeratedBool_result = enumeratedBool_parseS enumeratedBool_input-enumeratedBool_expects = (EnumerateBool {x' = True, y' = ON}, 0, "")-enumeratedBool_test = mkTestCase "EnumeratedBool" enumeratedBool_expects enumeratedBool_result--[pads| type NBA_char = (partition (Bits8 3, CharNB, Bits8 5) using none) |]--nBA_char_input = map word8ToChr [70,181] -- 01000110 10110101-nBA_char_result = nBA_char_parseS nBA_char_input-nBA_char_expects = ((2,'5',21), 0, "") -- 010 00110101 10101-nBA_char_test = mkTestCase "NBA_char" nBA_char_expects nBA_char_result--[pads| type NBA_char_aligned = (partition (CharNB, CharNB) using none)|]--nBA_char_aligned_input = map word8ToChr [70,181]-nBA_char_aligned_result = nBA_char_aligned_parseS nBA_char_aligned_input-nBA_char_aligned_expects = ((word8ToChr 70, word8ToChr 181), 0, "")-nBA_char_aligned_test = mkTestCase "NBA_char_aligned" nBA_char_aligned_expects nBA_char_aligned_result--[pads| type NBA_BS = (partition (Bits8 6, BytesNB 2, Bits8 2) using none) |]--nBA_BS_input = map word8ToChr [99,234,3] -- 01100011 11101010 0000011-nBA_BS_result = nBA_BS_parseS nBA_BS_input-nBA_BS_expects = ((24, B.pack [250,128], 3), 0, "")-nBA_BS_test = mkTestCase "NBA_BS" nBA_BS_expects nBA_BS_result--[pads| type NBA_BS_aligned = (partition (BytesNB 4) using none) |]--nBA_BS_aligned_input = map word8ToChr [9,8,7,255]-nBA_BS_aligned_result = nBA_BS_aligned_parseS nBA_BS_aligned_input-nBA_BS_aligned_expects = ((B.pack [9,8,7,255]), 0, "")-nBA_BS_aligned_test = mkTestCase "NBA_BS_aligned" nBA_BS_aligned_expects nBA_BS_aligned_result--[pads| type NBA_BS_empty = (partition (BytesNB 1) using none) |]--nBA_BS_empty_input = ""-nBA_BS_empty_result = nBA_BS_empty_parseS nBA_BS_empty_input-nBA_BS_empty_expects = ((B.singleton 0), 1, "")-nBA_BS_empty_test = mkTestCase "NBA_BS_empty" nBA_BS_empty_expects nBA_BS_empty_result--[pads| type NBA_StringFW = (partition (Bits8 4, StringFWNB 3, Bits8 4) using none) |]--nBA_StringFW_input = map word8ToChr [134,22,38,63] --1000 0110 0001 0110 0010 0110 0011 1111-nBA_StringFW_result = nBA_StringFW_parseS nBA_StringFW_input-nBA_StringFW_expects = ((8,"abc",15),0,"")-nBA_StringFW_test = mkTestCase "NBA_StringFW" nBA_StringFW_expects nBA_StringFW_result--[pads| type NBA_StringFW_aligned = (partition (StringFWNB 15) using none) |]--nBA_StringFW_aligned_input = map word8ToChr (replicate 15 97)-nBA_StringFW_aligned_result = nBA_StringFW_aligned_parseS nBA_StringFW_aligned_input-nBA_StringFW_aligned_expects = (("aaaaaaaaaaaaaaa"),0,"")-nBA_StringFW_aligned_test = mkTestCase "NBA_StringFW_aligned" nBA_StringFW_aligned_expects nBA_StringFW_aligned_result--[pads| type NBA_StringFW_err = (partition (StringFWNB 3) using none) |]--nBA_StringFW_err_input = map word8ToChr [99,99]-nBA_StringFW_err_result = nBA_StringFW_err_parseS nBA_StringFW_err_input-nBA_StringFW_err_expects = (("XXX"),1,"")-nBA_StringFW_err_test = mkTestCase "NBA_StringFW_err" nBA_StringFW_err_expects nBA_StringFW_err_result--[pads| type NBA_StringC = (partition (Bits8 2, StringCNB 'z', CharNB, Bits8 6) using none) |]--nBA_StringC_input = map word8ToChr [158,30,94,149] -- 10 011110 00 011110 01 011110 10 010101-nBA_StringC_result = nBA_StringC_parseS nBA_StringC_input-nBA_StringC_expects = ((2,"xy",'z',21),0,"")-nBA_StringC_test = mkTestCase "NBA_StringC" nBA_StringC_expects nBA_StringC_result--[pads| type NBA_StringC_aligned = (partition (StringCNB 'z') using none) |]--nBA_StringC_aligned_input = "xyz"-nBA_StringC_aligned_result = nBA_StringC_aligned_parseS nBA_StringC_aligned_input-nBA_StringC_aligned_expects = (("xy"),0,"z")-nBA_StringC_aligned_test = mkTestCase "NBA_StringC_aligned" nBA_StringC_aligned_expects nBA_StringC_aligned_result--$(make_pads_declarations $ map snd padsExp)--padsExp_ast =- [ ("Halloween", PadsDeclType "Halloween" [] Nothing- ( PList (PApp [PTycon ["StringFW"]] (Just (LitE (IntegerL 4))))- (Just (PTycon ["EOR"]))- (Just (LTerm (PTycon ["EOF"])))))]-padsExp_input = "karl\njred\nmatt\nsam_"-padsExp_result = halloween_parseS padsExp_input-padsExp_expects = (["karl", "jred", "matt", "sam_"], 0, "")-padsExp_test = TestCase (assertEqual "padsExp" padsExp padsExp_ast) -- mkTestCase "padsExp" padsExp padsExp_ast-padsExp_test2 = mkTestCase "padsExp" padsExp_expects padsExp_result------ | Regression tests need to be run from the root directory of the pads-haskell--- package because the data file paths in these test cases use paths relative to--- the root.-test = runTestTT (TestList tests)---tests = [ TestLabel "MyChar" myChar_test- , TestLabel "IntPair" intPair_test- , TestLabel "Bar" bar_test- , TestLabel "Bar2" bar2_test- , TestLabel "Bazr" bazr_test- , TestLabel "MyInt" myInt_test- , TestLabel "StrTy" strTy_test- , TestLabel "StrTy1" strTy1_test- , TestLabel "Baz" baz_test- , TestLabel "Phex32FW" phex32FW_test- , TestLabel "IntRange" test_intRange24- , TestLabel "IntRange" test_intRange0- , TestLabel "IntRange" test_intRange256- , TestLabel "IntRange" test_intRangeLow- , TestLabel "IntRange" test_intRangeHigh- , TestLabel "IntRange" test_intRangeBad- , TestLabel "IntRangeP" test_intRangeP24- , TestLabel "IntRangeP" test_intRangeP0- , TestLabel "IntRangeP" test_intRangeP256- , TestLabel "IntRangeP" test_intRangePLow- , TestLabel "IntRangeP" test_intRangePHigh- , TestLabel "IntRangeP" test_intRangePBad- , TestLabel "Record" test_Record- , TestLabel "Id" test_IdInt- , TestLabel "Id" test_IdStr- , TestLabel "Id" test_IdInt2- , TestLabel "Id" test_IdStr2- , TestLabel "Id3" test_IdInt3- , TestLabel "Id3" test_IdLit3- , TestLabel "Ab_or_a" test_Ab_or_a- , TestLabel "AB_test" test_AB_test1- , TestLabel "AB_test" test_AB_test2- , TestLabel "Method" test_method_get- , TestLabel "Method" test_method_put- , TestLabel "Method" test_method_link- , TestLabel "Method" test_method_post- , TestLabel "Version" test_version- , TestLabel "Request" test_request_G- , TestLabel "Request" test_request_B- , TestLabel "Eor" test_eor_test- , TestLabel "Eof" test_eof_test_G- , TestLabel "Eof" test_eof_test_B- , TestLabel "Opt" test_opt_test_j- , TestLabel "Opt" test_opt_test_n- , TestLabel "List" test_entries_nosep_noterm- , TestLabel "List" test_entries_nosep_noterm'- , TestLabel "List" test_entries_nosep_noterm2- , TestLabel "List" test_evenInt- , TestLabel "List" test_evenInts- , TestLabel "List" test_digitListG- , TestLabel "List" test_digitList2G- , TestLabel "List" test_digitListB- , TestLabel "List" test_digitListLenG- , TestLabel "List" test_digitListLenB- , TestLabel "List" test_digitListLenSepG- , TestLabel "List" test_digitListLenSepB- , TestLabel "List" test_digitListTermG- , TestLabel "List" test_digitListTermB- , TestLabel "List" test_digitListTermSepG- , TestLabel "List" test_digitListTermSepB- , TestLabel "Try" test_tryTest- , TestLabel "Try" test_tryTestDG- , TestLabel "Try" test_tryTestDB- , TestLabel "Try" test_ListWithTry- , TestLabel "Void" test_WithVoid- , TestLabel "Void" test_voidEntry1- , TestLabel "Void" test_voidEntry2- , TestLabel "Void" test_voidEntry3- , TestLabel "Switch" test_switch0- , TestLabel "Switch" test_switch1- , TestLabel "Switch" test_switchOther- , TestLabel "Stringln" test_stringln- , TestLabel "Compound" test_myData- , TestLabel "Compound" test_hp_data- , TestLabel "Doc" test_hp_data_file_parse- , TestLabel "Doc" myDoc_test- , TestLabel "Literal" litRec_test- , TestLabel "Literal" whiteSpace_test- , TestLabel "Literal" whiteSpace2_test- , TestLabel "Regular Expression" rE_ty_test- , TestLabel "Discipline" disc_test- , TestLabel "Overlap" exxy_test- , TestLabel "Discipline" linesFW_test- , TestLabel "Values" vals_test- , TestLabel "Values" vals2_test- , TestLabel "Double" doubles_test- , TestLabel "StringSE" stringSEs_test- , TestLabel "StringFWs" stringFWs_test- , TestLabel "StringESCs" stringESCs_test- , TestLabel "StringPs" stringPs_test- , TestLabel "PadsExp" padsExp_test- , TestLabel "PadsExp2" padsExp_test2- , TestLabel "BitBools" bitBools_test- , TestLabel "BitBools" bitBools_test2- , TestLabel "ArithPixel" arithPixel_test- , TestLabel "IncompleteBitBools" incompleteBitBools_test- , TestLabel "Mixed" mixed_test- , TestLabel "OddWidths" oddWidths_test- , TestLabel "LargeWidths" largeWidths_test- , TestLabel "Enumerated" enumerated_test- , TestLabel "EnumeratedWC" enumerated_test_wc- , TestLabel "EnumeratedBool" enumeratedBool_test- , TestLabel "NBA_char" nBA_char_test- , TestLabel "NBA_char_aligned" nBA_char_aligned_test- , TestLabel "NBA_BS" nBA_BS_test- , TestLabel "NBA_BS_aligned" nBA_BS_aligned_test- , TestLabel "NBA_BS_empty" nBA_BS_empty_test- , TestLabel "NBA_StringFW" nBA_StringFW_test- , TestLabel "NBA_StringFW_aligned" nBA_StringFW_aligned_test- , TestLabel "NBA_StringFW_err" nBA_StringFW_err_test- , TestLabel "NBA_StringC" nBA_StringC_test- , TestLabel "NBA_StringC_aligned" nBA_StringC_aligned_test- ]
@@ -1,8 +0,0 @@-{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,- MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,- DeriveDataTypeable, ScopedTypeVariables #-}-module Examples.FirstPads where-import Language.Pads.Padsc--padsExp = [pads| type Halloween = [StringFW 4 | EOR] terminator EOF |]-
@@ -1,51 +0,0 @@-{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable- , MultiParamTypeClasses- , TypeSynonymInstances- , TemplateHaskell- , QuasiQuotes- , FlexibleInstances #-}--- :set -ddump-splices-module Examples.Proc where-import Language.Pads.Padsc--ws = RE "[ \t]+"--[pads|-- newtype MapsFile = MapsFile ([Line Region] terminator EOF)- - data Region = Region- { start_addr :: Hex- , '-', end_addr :: Hex- , ' ', perms :: Permissions- , ' ', offset :: Int- , ' ', device :: (Hex, ':', Hex)- , ' ', inode :: Int- , ws , path :: RegionName- }-- type Hex = StringME '[0-9A-Fa-f]+'-- data RegionName =- Heap "[heap]"- | Stack "[stack]"- | VDSO "[vdso]"- | VVAR "[vvar]"- | VSyscall "[vsyscall]"- | Path ([Char] terminator EOR)- | Anonymous ""-- data Permissions = Permissions- { permRead :: RP- , permWrite :: WP- , permExec :: XP- , permShare :: SP- }-- data RP = READ 'r' | NOREAD '-'- data WP = WRITE 'w' | NOWRITE '-'- data XP = EXEC 'x' | NOEXEC '-'- data SP = SHARE 's' | PRIVATE 'p'--|]-
@@ -1,24 +0,0 @@-This directory contains data for example programs.--For Examples/First.hs- Examples/data/test_file--For Examples/AI.hs- Examples/data/ai.3000- Examples/data/ai.big--For Examples/Binary.hs- Examples/data/binary -- Small input test file- Call Detail Records- Examples/data/a2b.c -- C program to convert ascii records to binary- -- To compile: cc -o a2b a2b.c- -- To run: a2b < calls10.a > calls10.b- Examples/data/calls10.a, -- ASCII call detail records- Examples/data/calls10.b, -- Corresponding binary records- - Binary base type tseting- Examples/data/genBin.c, -- C program to convert ascii records to binary- -- To compile: cc -o genBin binTest.a- -- To run: genBin < binTest.a > binTest.b- Examples/data/binTest.a, - Examples/data/binTest.b
@@ -1,34 +0,0 @@-#include <stdio.h>--/* Reads ascii call detail records from stdin.- * Writes scampRec binary call detail records on stdout.- */--typedef struct-{- int onpa, obase;- int dnpa, dbase;- int con;- int dur; -} scampRec_t;----int readAscii(FILE *in, scampRec_t *r){- int success = fscanf(in, "%d %d %d %d %d %d\n",- &(r->onpa), &(r->obase), - &(r->dnpa), &(r->dbase),- &(r->con), &(r->dur)); - return success;-}--void writeBinary(FILE *out, scampRec_t *r){- fwrite(r, sizeof(scampRec_t), 1, out);-}--int main(){- scampRec_t current;- while (readAscii(stdin, ¤t) != EOF)- writeBinary(stdout, ¤t);- return 0;-}
@@ -1,3001 +0,0 @@-207.136.97.49 - - [15/Oct/1997:18:46:51 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-207.136.97.49 - - [15/Oct/1997:18:46:51 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-207.136.97.49 - - [15/Oct/1997:18:46:52 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-207.136.97.49 - - [15/Oct/1997:18:46:52 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-208.196.124.26 - - [15/Oct/1997:18:46:55 -0700] "GET /candatop.html HTTP/1.0" 200 10629-208.196.124.26 - - [15/Oct/1997:18:46:57 -0700] "GET /images/done.gif HTTP/1.0" 200 4785-208.196.124.26 - - [15/Oct/1997:18:47:01 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237-208.196.124.26 - - [15/Oct/1997:18:47:02 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836-208.196.124.26 - - [15/Oct/1997:18:47:05 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833-208.196.124.26 - - [15/Oct/1997:18:47:08 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638-208.196.124.26 - - [15/Oct/1997:18:47:09 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429-208.196.124.26 - - [15/Oct/1997:18:47:09 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352-128.200.68.71 - - [15/Oct/1997:18:47:11 -0700] "GET /amnesty/usalinks.html HTTP/1.0" 200 10329-208.196.124.26 - - [15/Oct/1997:18:47:11 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859-128.200.68.71 - - [15/Oct/1997:18:47:12 -0700] "GET /amnesty/images/ai_cand1.gif HTTP/1.0" 200 6328-128.200.68.71 - - [15/Oct/1997:18:47:12 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-128.200.68.71 - - [15/Oct/1997:18:47:13 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-208.196.124.26 - - [15/Oct/1997:18:47:14 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903-128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-128.200.68.71 - - [15/Oct/1997:18:47:16 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-!! BAD LINE !!-208.196.124.26 - - [15/Oct/1997:18:47:16 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-128.200.68.71 - - [15/Oct/1997:18:47:19 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-208.196.124.26 - - [15/Oct/1997:18:47:21 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625-208.196.124.26 - - [15/Oct/1997:18:47:23 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-208.196.124.26 - - [15/Oct/1997:18:47:23 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-208.196.124.26 - - [15/Oct/1997:18:47:24 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-208.196.124.26 - - [15/Oct/1997:18:47:32 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-208.196.124.26 - - [15/Oct/1997:18:47:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-128.200.68.71 - - [15/Oct/1997:18:48:01 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902-128.200.68.71 - - [15/Oct/1997:18:48:02 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509-128.200.68.71 - - [15/Oct/1997:18:48:02 -0700] "GET /amnesty/images/whobut.gif HTTP/1.0" 200 505-128.200.68.71 - - [15/Oct/1997:18:48:04 -0700] "GET /amnesty/images/aalogo.gif HTTP/1.0" 200 15293-128.200.68.71 - - [15/Oct/1997:18:48:05 -0700] "GET /amnesty/images/whatbut.gif HTTP/1.0" 200 526-128.200.68.71 - - [15/Oct/1997:18:48:05 -0700] "GET /amnesty/images/where.gif HTTP/1.0" 200 605-206.175.186.71 - - [15/Oct/1997:18:48:07 -0700] "GET /amnesty/immigr.html HTTP/1.0" 200 11284-128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-128.200.68.71 - - [15/Oct/1997:18:48:09 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-128.200.68.71 - - [15/Oct/1997:18:48:35 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629-128.200.68.71 - - [15/Oct/1997:18:48:36 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785-128.200.68.71 - - [15/Oct/1997:18:48:37 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638-128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352-128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859-128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-128.200.68.71 - - [15/Oct/1997:18:48:39 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625-128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833-128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429-128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237-128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836-128.200.68.71 - - [15/Oct/1997:18:48:41 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-128.200.68.71 - - [15/Oct/1997:18:48:44 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903-128.200.68.71 - - [15/Oct/1997:18:49:17 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-128.200.68.71 - - [15/Oct/1997:18:49:17 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-148.4.61.168 - - [15/Oct/1997:18:49:22 -0700] "GET / HTTP/1.0" 200 3082-128.200.68.71 - - [15/Oct/1997:18:49:22 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-128.200.68.71 - - [15/Oct/1997:18:49:23 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-128.200.68.71 - - [15/Oct/1997:18:49:24 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-128.200.68.71 - - [15/Oct/1997:18:49:24 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-148.4.61.168 - - [15/Oct/1997:18:49:24 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-128.200.68.71 - - [15/Oct/1997:18:49:25 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-128.200.68.71 - - [15/Oct/1997:18:49:25 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-148.4.61.168 - - [15/Oct/1997:18:49:28 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-128.200.68.71 - - [15/Oct/1997:18:49:30 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-128.200.68.71 - - [15/Oct/1997:18:49:31 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-148.4.61.168 - - [15/Oct/1997:18:49:37 -0700] "GET /joinai.html HTTP/1.0" 200 4054-148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-148.4.61.168 - - [15/Oct/1997:18:49:39 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-148.4.61.168 - - [15/Oct/1997:18:49:39 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-148.4.61.168 - - [15/Oct/1997:18:49:41 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-148.4.61.168 - - [15/Oct/1997:18:51:48 -0700] "POST /scripts/mailform/aimember@aiusa.org/confirm HTTP/1.0" 200 553-148.4.61.168 - - [15/Oct/1997:18:51:49 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-148.4.61.168 - - [15/Oct/1997:18:51:59 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-148.4.61.168 - - [15/Oct/1997:18:52:33 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629-148.4.61.168 - - [15/Oct/1997:18:52:35 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237-148.4.61.168 - - [15/Oct/1997:18:52:35 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859-148.4.61.168 - - [15/Oct/1997:18:52:37 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836-148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638-148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833-148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429-148.4.61.168 - - [15/Oct/1997:18:52:39 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352-148.4.61.168 - - [15/Oct/1997:18:52:40 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625-148.4.61.168 - - [15/Oct/1997:18:52:41 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-148.4.61.168 - - [15/Oct/1997:18:52:42 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509-148.4.61.168 - - [15/Oct/1997:18:52:42 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903-148.4.61.168 - - [15/Oct/1997:18:52:43 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785-148.4.61.168 - - [15/Oct/1997:18:53:14 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-148.4.61.168 - - [15/Oct/1997:18:53:14 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-148.4.61.168 - - [15/Oct/1997:18:53:16 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-148.4.61.168 - - [15/Oct/1997:18:53:16 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-148.4.61.168 - - [15/Oct/1997:18:53:17 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-208.151.41.69 - - [15/Oct/1997:18:53:29 -0700] "GET /country/balkans HTTP/1.0" 301 196-128.200.68.71 - - [15/Oct/1997:18:53:30 -0700] "GET /amnesty/about/history.html HTTP/1.0" 200 10342-128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/about/images/airmail2.jpg HTTP/1.0" 200 7820-128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/about/images/coverbut.gif HTTP/1.0" 200 400-128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-208.151.41.69 - - [15/Oct/1997:18:53:31 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/about/images/backtono.gif HTTP/1.0" 200 2367-128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/about/images/sagan4.gif HTTP/1.0" 200 3596-128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786-128.200.68.71 - - [15/Oct/1997:18:53:33 -0700] "GET /amnesty/about/images/masthd3.gif HTTP/1.0" 200 33250-128.200.68.71 - - [15/Oct/1997:18:53:33 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-208.151.41.69 - - [15/Oct/1997:18:53:33 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-208.151.41.69 - - [15/Oct/1997:18:53:35 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-208.151.41.69 - - [15/Oct/1997:18:53:35 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-208.151.41.69 - - [15/Oct/1997:18:53:36 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-208.151.41.69 - - [15/Oct/1997:18:53:37 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-207.228.67.219 - - [15/Oct/1997:18:53:47 -0700] "GET / HTTP/1.0" 200 3082-207.228.67.219 - - [15/Oct/1997:18:53:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-207.228.67.219 - - [15/Oct/1997:18:53:55 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-128.200.68.71 - - [15/Oct/1997:18:54:03 -0700] "GET /amnesty/feats/wamphoto.html HTTP/1.0" 200 6567-128.200.68.71 - - [15/Oct/1997:18:54:04 -0700] "GET /amnesty/images/opencuf2.jpg HTTP/1.0" 200 2581-207.228.67.219 - - [15/Oct/1997:18:54:04 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-128.200.68.71 - - [15/Oct/1997:18:54:05 -0700] "GET /amnesty/images/wamwere.gif HTTP/1.0" 200 19858-207.228.67.219 - - [15/Oct/1997:18:54:08 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483-207.228.67.219 - - [15/Oct/1997:18:54:10 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498-207.228.67.219 - - [15/Oct/1997:18:54:17 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-207.228.67.219 - - [15/Oct/1997:18:54:24 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848-207.228.67.219 - - [15/Oct/1997:18:54:32 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585-128.200.68.71 - - [15/Oct/1997:18:54:35 -0700] "GET /amnesty/ann-rpt.html HTTP/1.0" 200 1899-207.228.67.219 - - [15/Oct/1997:18:54:40 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-207.228.67.219 - - [15/Oct/1997:18:54:58 -0700] "GET /comm/honor2.html HTTP/1.0" 200 10981-128.200.68.71 - - [15/Oct/1997:18:55:01 -0700] "GET /amnesty/ar-sum.html HTTP/1.0" 200 27608-128.200.68.71 - - [15/Oct/1997:18:55:07 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-207.228.67.219 - - [15/Oct/1997:18:55:08 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517-207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/jagger3.jpg HTTP/1.0" 200 4864-207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/stew3.jpg HTTP/1.0" 200 5558-207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/wallace3.jpg HTTP/1.0" 200 5348-207.228.67.219 - - [15/Oct/1997:18:55:36 -0700] "GET /comm/images/people/berman3.jpg HTTP/1.0" 200 4705-207.228.67.219 - - [15/Oct/1997:18:55:40 -0700] "GET /comm/images/people/bailey3.jpg HTTP/1.0" 200 4565-207.228.67.219 - - [15/Oct/1997:18:55:41 -0700] "GET /comm/images/people/herbert3.jpg HTTP/1.0" 200 4819-207.228.67.219 - - [15/Oct/1997:18:55:43 -0700] "GET /comm/images/spot05.gif HTTP/1.0" 200 8192-207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-207.228.67.219 - - [15/Oct/1997:18:55:57 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-207.228.67.219 - - [15/Oct/1997:18:55:59 -0700] "GET /home.html HTTP/1.0" 200 17233-207.228.67.219 - - [15/Oct/1997:18:55:59 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:01 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-207.228.67.219 - - [15/Oct/1997:18:56:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:03 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-207.228.67.219 - - [15/Oct/1997:18:56:04 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-207.228.67.219 - - [15/Oct/1997:18:56:06 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:07 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-207.228.67.219 - - [15/Oct/1997:18:56:07 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:08 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:08 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-207.228.67.219 - - [15/Oct/1997:18:56:09 -0700] "GET /images/countbut.gif HTTP/1.0" 304 --207.228.67.219 - - [15/Oct/1997:18:56:11 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-207.228.67.219 - - [15/Oct/1997:18:56:12 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-207.228.67.219 - - [15/Oct/1997:18:56:12 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-207.228.67.219 - - [15/Oct/1997:18:56:15 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-207.228.67.219 - - [15/Oct/1997:18:56:33 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-128.200.68.71 - - [15/Oct/1997:18:56:46 -0700] "GET /amnesty/mandate.html HTTP/1.0" 200 21981-148.4.61.168 - - [15/Oct/1997:18:56:55 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483-148.4.61.168 - - [15/Oct/1997:18:56:56 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498-148.4.61.168 - - [15/Oct/1997:18:56:56 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-148.4.61.168 - - [15/Oct/1997:18:56:57 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848-148.4.61.168 - - [15/Oct/1997:18:56:57 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-148.4.61.168 - - [15/Oct/1997:18:57:00 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585-148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /home.html HTTP/1.0" 200 17233-148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-148.4.61.168 - - [15/Oct/1997:18:57:43 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-148.4.61.168 - - [15/Oct/1997:18:57:45 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-207.67.28.158 - - [15/Oct/1997:18:58:12 -0700] "GET /refugee HTTP/1.0" 301 188-207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836-207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/turqbut.gif HTTP/1.0" 200 903-207.67.28.158 - - [15/Oct/1997:18:58:18 -0700] "GET /refugee/ HTTP/1.0" 200 18751-207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/morinfox.gif HTTP/1.0" 200 2056-207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-148.4.61.168 - - [15/Oct/1997:18:58:50 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-148.4.61.168 - - [15/Oct/1997:18:58:54 -0700] "GET /about.html HTTP/1.0" 200 6902-148.4.61.168 - - [15/Oct/1997:18:58:55 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-148.4.61.168 - - [15/Oct/1997:18:58:55 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-148.4.61.168 - - [15/Oct/1997:18:58:56 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-148.4.61.168 - - [15/Oct/1997:18:58:57 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-148.4.61.168 - - [15/Oct/1997:18:58:57 -0700] "GET /images/where.gif HTTP/1.0" 200 605-148.4.61.168 - - [15/Oct/1997:18:59:00 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-136.168.101.17 - - [15/Oct/1997:18:59:09 -0700] "GET / HTTP/1.0" 200 3082-207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-207.67.28.158 - - [15/Oct/1997:18:59:10 -0700] "GET /home.html HTTP/1.0" 200 17233-136.168.101.17 - - [15/Oct/1997:18:59:10 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-207.67.28.158 - - [15/Oct/1997:18:59:11 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-207.67.28.158 - - [15/Oct/1997:18:59:12 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-136.168.101.17 - - [15/Oct/1997:18:59:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-207.67.28.158 - - [15/Oct/1997:18:59:13 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-207.67.28.158 - - [15/Oct/1997:18:59:13 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-207.67.28.158 - - [15/Oct/1997:18:59:15 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-24.64.22.142 - - [15/Oct/1997:18:59:18 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527-207.67.28.158 - - [15/Oct/1997:18:59:18 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-207.67.28.158 - - [15/Oct/1997:18:59:18 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368-24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380-24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363-24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399-207.67.28.158 - - [15/Oct/1997:18:59:19 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-24.64.22.142 - - [15/Oct/1997:18:59:20 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317-24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329-24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384-24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352-24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366-24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383-207.67.28.158 - - [15/Oct/1997:18:59:21 -0700] "GET /write.html HTTP/1.0" 200 9408-24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352-24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432-24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403-207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166-24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592-24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344-24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359-24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352-207.67.28.158 - - [15/Oct/1997:18:59:23 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /about.html HTTP/1.0" 200 6902-136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-136.168.101.17 - - [15/Oct/1997:18:59:27 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-136.168.101.17 - - [15/Oct/1997:18:59:27 -0700] "GET /images/where.gif HTTP/1.0" 200 605-136.168.101.17 - - [15/Oct/1997:18:59:28 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-136.168.101.17 - - [15/Oct/1997:18:59:30 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/iran.html HTTP/1.0" 200 8412-24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/iran.jpg HTTP/1.0" 200 3240-24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/irnflag.gif HTTP/1.0" 200 2273-24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202-207.67.28.158 - - [15/Oct/1997:19:00:19 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-207.67.28.158 - - [15/Oct/1997:19:00:19 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887-207.67.28.158 - - [15/Oct/1997:19:00:20 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308-24.64.22.142 - - [15/Oct/1997:19:00:28 -0700] "GET /amnesty/mideast/index.html HTTP/1.0" 200 3104-24.64.22.142 - - [15/Oct/1997:19:00:29 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682-24.64.22.142 - - [15/Oct/1997:19:00:35 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216-148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /group.html HTTP/1.0" 200 8575-148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161-148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471-148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-148.4.61.168 - - [15/Oct/1997:19:01:01 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013-148.4.61.168 - - [15/Oct/1997:19:01:01 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399-148.4.61.168 - - [15/Oct/1997:19:01:02 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257-148.4.61.168 - - [15/Oct/1997:19:01:06 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-148.4.61.168 - - [15/Oct/1997:19:01:07 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430-24.64.22.142 - - [15/Oct/1997:19:01:08 -0700] "GET /amnesty/mideast/counfram.html HTTP/1.0" 200 1145-24.64.22.142 - - [15/Oct/1997:19:01:09 -0700] "GET /amnesty/mideast/algeria.html HTTP/1.0" 200 7945-24.64.22.142 - - [15/Oct/1997:19:01:10 -0700] "GET /amnesty/mideast/algeria.jpg HTTP/1.0" 200 5485-24.64.22.142 - - [15/Oct/1997:19:01:10 -0700] "GET /amnesty/mideast/algflag.gif HTTP/1.0" 200 1902-204.162.96.92 - - [15/Oct/1997:19:01:14 -0700] "GET /robots.txt HTTP/1.0" 404 163-204.162.96.92 - - [15/Oct/1997:19:01:25 -0700] "GET /education/ HTTP/1.0" 200 9100-207.67.28.158 - - [15/Oct/1997:19:01:31 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-207.67.28.158 - - [15/Oct/1997:19:01:34 -0700] "GET /urgact/newslett.html HTTP/1.0" 200 26074-207.67.28.158 - - [15/Oct/1997:19:02:12 -0700] "GET /urgact/index.html HTTP/1.0" 200 8283-207.67.28.158 - - [15/Oct/1997:19:02:40 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-207.67.28.158 - - [15/Oct/1997:19:02:42 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-207.67.28.158 - - [15/Oct/1997:19:02:42 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-207.67.28.158 - - [15/Oct/1997:19:02:48 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-207.67.28.158 - - [15/Oct/1997:19:02:53 -0700] "GET /welcome.html HTTP/1.0" 200 4731-207.67.28.158 - - [15/Oct/1997:19:02:55 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-207.67.28.158 - - [15/Oct/1997:19:02:55 -0700] "GET /images/never.gif HTTP/1.0" 200 914-207.67.28.158 - - [15/Oct/1997:19:02:56 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924-207.67.28.158 - - [15/Oct/1997:19:03:00 -0700] "GET /images/commit.gif HTTP/1.0" 200 190-207.67.28.158 - - [15/Oct/1997:19:03:00 -0700] "GET /images/your.gif HTTP/1.0" 200 951-207.67.28.158 - - [15/Oct/1997:19:03:01 -0700] "GET /images/rights.gif HTTP/1.0" 200 938-207.67.28.158 - - [15/Oct/1997:19:03:02 -0700] "GET /images/can.gif HTTP/1.0" 200 946-207.67.28.158 - - [15/Oct/1997:19:03:04 -0700] "GET /images/a.gif HTTP/1.0" 200 865-207.67.28.158 - - [15/Oct/1997:19:03:04 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882-207.67.28.158 - - [15/Oct/1997:19:03:05 -0700] "GET /images/differ.gif HTTP/1.0" 200 191-204.162.96.93 - - [15/Oct/1997:19:03:06 -0700] "GET /amnesty/regions/maregcon.html HTTP/1.0" 200 1304-207.67.28.158 - - [15/Oct/1997:19:03:06 -0700] "GET /images/canred.gif HTTP/1.0" 200 311-207.67.28.158 - - [15/Oct/1997:19:03:08 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-207.67.28.158 - - [15/Oct/1997:19:03:11 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157-148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-207.67.28.158 - - [15/Oct/1997:19:03:13 -0700] "GET /images/it.gif HTTP/1.0" 200 170-148.4.61.168 - - [15/Oct/1997:19:03:13 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-148.4.61.168 - - [15/Oct/1997:19:03:13 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-148.4.61.168 - - [15/Oct/1997:19:03:14 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-207.67.28.158 - - [15/Oct/1997:19:03:16 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591-207.67.28.158 - - [15/Oct/1997:19:03:17 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581-148.4.61.168 - - [15/Oct/1997:19:03:17 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-207.67.28.158 - - [15/Oct/1997:19:03:19 -0700] "GET /images/human.gif HTTP/1.0" 200 155-207.67.28.158 - - [15/Oct/1997:19:03:27 -0700] "GET /postcard/welact.html HTTP/1.0" 200 4640-207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/joinbut.gif HTTP/1.0" 200 409-207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/w.gif HTTP/1.0" 200 565-207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/welbut.gif HTTP/1.0" 200 600-207.67.28.158 - - [15/Oct/1997:19:03:30 -0700] "GET /postcard/images/letbut.gif HTTP/1.0" 200 517-207.67.28.158 - - [15/Oct/1997:19:03:31 -0700] "GET /postcard/images/aiusabut.gif HTTP/1.0" 200 591-207.67.28.158 - - [15/Oct/1997:19:03:41 -0700] "GET /postcard/images/wombarb9.gif HTTP/1.0" 200 20647-148.4.61.168 - - [15/Oct/1997:19:04:34 -0700] "GET /members.html HTTP/1.0" 200 1501-148.4.61.168 - - [15/Oct/1997:19:04:35 -0700] "GET /images/memlogo.gif HTTP/1.0" 200 7872-148.4.61.168 - - [15/Oct/1997:19:04:49 -0700] "GET /members/index.html HTTP/1.0" 401 350-148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-148.4.61.168 - - [15/Oct/1997:19:05:20 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-148.4.61.168 - - [15/Oct/1997:19:05:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-152.163.207.138 - - [15/Oct/1997:19:05:54 -0700] "GET / HTTP/1.0" 200 3082-152.163.207.138 - - [15/Oct/1997:19:06:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-152.163.207.138 - - [15/Oct/1997:19:06:03 -0700] "GET /images/spot5.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:06:52 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-152.163.207.138 - - [15/Oct/1997:19:06:56 -0700] "GET /images/pandnlog.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:06:59 -0700] "GET /images/ganbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:00 -0700] "GET /images/campbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:02 -0700] "GET /images/deathbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:02 -0700] "GET /images/groupbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:03 -0700] "GET /images/dot.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:04 -0700] "GET /images/uabut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:05 -0700] "GET /images/refbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:07 -0700] "GET /images/ncasebut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:08 -0700] "GET /images/lgbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:09 -0700] "GET /images/educbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:09 -0700] "GET /images/healbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:11 -0700] "GET /images/legalbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:12 -0700] "GET /images/womenbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:12 -0700] "GET /images/wordo35d.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:14 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:15 -0700] "GET /images/penhand3.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:16 -0700] "GET /images/kids3.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:16 -0700] "GET /images/womland2.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:21 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:22 -0700] "GET /images/homebut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:07:23 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:04 -0700] "GET /candatop.html HTTP/1.0" 200 10629-152.163.207.138 - - [15/Oct/1997:19:08:08 -0700] "GET /images/candalog.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:09 -0700] "GET /images/done.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:11 -0700] "GET /images/hasene2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:11 -0700] "GET /images/rally4.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/reddash2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/refrun1.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/reyes.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:14 -0700] "GET /images/kids5.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:15 -0700] "GET /images/nigpost1.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:16 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:17 -0700] "GET /images/howbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:08:19 -0700] "GET /images/turkboy.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:09:18 -0700] "GET / HTTP/1.0" 200 --206.175.189.221 - - [15/Oct/1997:19:09:29 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-206.175.189.221 - - [15/Oct/1997:19:09:32 -0700] "GET /images/spot5.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:09:33 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-152.163.207.138 - - [15/Oct/1997:19:09:36 -0700] "GET /group.html HTTP/1.0" 200 8575-152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/can1_2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/goldfla2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/grncndl.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:44 -0700] "GET /images/04candle.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:44 -0700] "GET /images/canfuz1.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:47 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:53 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:54 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:58 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:09:58 -0700] "GET /images/evenbut.gif HTTP/1.0" 304 --136.168.101.19 - - [15/Oct/1997:19:10:07 -0700] "GET / HTTP/1.0" 200 3082-136.168.101.19 - - [15/Oct/1997:19:10:08 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-136.168.101.19 - - [15/Oct/1997:19:10:09 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-206.175.189.221 - - [15/Oct/1997:19:10:10 -0700] "GET /write.html HTTP/1.0" 200 9408-206.175.189.221 - - [15/Oct/1997:19:10:12 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166-206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:10:15 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:10:16 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:10:16 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --136.168.101.19 - - [15/Oct/1997:19:10:28 -0700] "GET /about.html HTTP/1.0" 200 6902-136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/where.gif HTTP/1.0" 200 605-136.168.101.19 - - [15/Oct/1997:19:10:31 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-136.168.101.19 - - [15/Oct/1997:19:10:32 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-136.168.101.19 - - [15/Oct/1997:19:10:32 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-152.163.207.138 - - [15/Oct/1997:19:10:39 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:11:12 -0700] "GET /joinai.html HTTP/1.0" 200 4054-206.175.189.221 - - [15/Oct/1997:19:11:14 -0700] "GET /weeklyua.html HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:11:16 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:11:16 -0700] "GET /images/linebrn.gif HTTP/1.0" 304 --206.175.189.221 - - [15/Oct/1997:19:11:16 -0700] "GET /images/logo2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:11:37 -0700] "GET /home.html HTTP/1.0" 200 17233-152.163.207.138 - - [15/Oct/1997:19:11:43 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:11:56 -0700] "GET /ainews.html HTTP/1.0" 200 13435-152.163.207.138 - - [15/Oct/1997:19:12:08 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:10 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:12 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:12 -0700] "GET /images/refhand4.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:14 -0700] "GET /images/countbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:16 -0700] "GET /images/netbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:16 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:17 -0700] "GET /images/joinbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:19 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:20 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:12:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:09 -0700] "GET /feats/weij.html HTTP/1.0" 200 6121-152.163.205.106 - - [15/Oct/1997:19:13:21 -0700] "GET /casework/fw.html HTTP/1.0" 304 --152.163.205.106 - - [15/Oct/1997:19:13:24 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 304 --152.163.205.106 - - [15/Oct/1997:19:13:24 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:33 -0700] "GET /asa/china/ HTTP/1.0" 200 18000-152.163.207.138 - - [15/Oct/1997:19:13:37 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336-152.163.207.138 - - [15/Oct/1997:19:13:51 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:53 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-152.163.207.138 - - [15/Oct/1997:19:13:54 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:57 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:57 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:13:58 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122-152.163.207.138 - - [15/Oct/1997:19:13:59 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:14:01 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983-152.163.205.106 - - [15/Oct/1997:19:14:09 -0700] "GET /casework/fwq&a.html HTTP/1.0" 200 6329-152.163.207.138 - - [15/Oct/1997:19:14:12 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:14:13 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411-152.163.207.138 - - [15/Oct/1997:19:14:15 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:14:15 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:14:16 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794-152.163.207.138 - - [15/Oct/1997:19:14:18 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202-152.163.207.138 - - [15/Oct/1997:19:14:19 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648-152.163.207.138 - - [15/Oct/1997:19:14:27 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:14:33 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:15:55 -0700] "GET /asa/china/images/blue.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:15:57 -0700] "GET /asa/china/tibet.html HTTP/1.0" 200 8882-152.163.205.106 - - [15/Oct/1997:19:16:03 -0700] "GET /casework/fw1.html HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:16:04 -0700] "GET /asa/china/images/cgyatso2.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:16:04 -0700] "GET /asa/china/images/mainmenu.gif HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:16:06 -0700] "GET /asa/china/images/cohen.jpg HTTP/1.0" 304 --152.163.207.138 - - [15/Oct/1997:19:16:55 -0700] "GET /asa/china/TRANS.GIF HTTP/1.0" 404 172-152.163.207.138 - - [15/Oct/1997:19:16:55 -0700] "GET /asa/china/cando.html HTTP/1.0" 200 8129-152.163.207.138 - - [15/Oct/1997:19:17:00 -0700] "GET /asa/china/images/mailme.gif HTTP/1.0" 200 14893-136.168.221.19 - - [15/Oct/1997:19:17:10 -0700] "GET / HTTP/1.0" 200 3082-136.168.221.19 - - [15/Oct/1997:19:17:12 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-136.168.221.19 - - [15/Oct/1997:19:17:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-136.168.221.19 - - [15/Oct/1997:19:17:16 -0700] "GET /about.html HTTP/1.0" 200 6902-152.163.207.138 - - [15/Oct/1997:19:17:16 -0700] "GET /asa/china/images/punchy.gif HTTP/1.0" 304 --136.168.221.19 - - [15/Oct/1997:19:17:17 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-136.168.221.19 - - [15/Oct/1997:19:17:17 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-136.168.221.19 - - [15/Oct/1997:19:17:18 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-152.163.207.138 - - [15/Oct/1997:19:17:19 -0700] "GET /asa/china/images/world.gif HTTP/1.0" 304 --136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/where.gif HTTP/1.0" 200 605-136.168.221.19 - - [15/Oct/1997:19:17:22 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-136.168.221.19 - - [15/Oct/1997:19:17:22 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-136.168.221.19 - - [15/Oct/1997:19:17:23 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-136.168.221.19 - - [15/Oct/1997:19:17:25 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-136.168.221.19 - - [15/Oct/1997:19:18:51 -0700] "GET /about/history.html HTTP/1.0" 200 10342-136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250-136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-136.168.221.19 - - [15/Oct/1997:19:18:53 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820-136.168.221.19 - - [15/Oct/1997:19:18:53 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367-136.168.221.19 - - [15/Oct/1997:19:18:54 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-136.168.221.19 - - [15/Oct/1997:19:18:55 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400-136.168.221.19 - - [15/Oct/1997:19:18:56 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-136.168.221.19 - - [15/Oct/1997:19:18:56 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-136.168.221.19 - - [15/Oct/1997:19:18:57 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596-152.171.10.6 - - [15/Oct/1997:19:19:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-152.171.10.6 - - [15/Oct/1997:19:19:18 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-152.171.10.6 - - [15/Oct/1997:19:19:22 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-152.171.10.6 - - [15/Oct/1997:19:20:49 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-152.171.10.6 - - [15/Oct/1997:19:20:53 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-152.171.10.6 - - [15/Oct/1997:19:21:00 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-152.171.10.6 - - [15/Oct/1997:19:21:07 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-199.217.72.166 - - [15/Oct/1997:19:27:19 -0700] "GET /country/balkans HTTP/1.0" 301 196-199.217.72.166 - - [15/Oct/1997:19:27:21 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-199.217.72.166 - - [15/Oct/1997:19:27:23 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-199.217.72.166 - - [15/Oct/1997:19:27:24 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-199.217.72.166 - - [15/Oct/1997:19:27:26 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-199.217.72.166 - - [15/Oct/1997:19:27:26 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-199.217.72.166 - - [15/Oct/1997:19:27:30 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-199.217.72.166 - - [15/Oct/1997:19:27:30 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-199.217.72.166 - - [15/Oct/1997:19:27:42 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-199.217.72.166 - - [15/Oct/1997:19:27:42 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-203.18.134.1 - - [15/Oct/1997:19:27:44 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-203.18.134.1 - - [15/Oct/1997:19:27:46 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-203.18.134.1 - - [15/Oct/1997:19:27:47 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-203.18.134.1 - - [15/Oct/1997:19:27:48 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-203.18.134.1 - - [15/Oct/1997:19:27:49 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-203.18.134.1 - - [15/Oct/1997:19:27:50 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-203.18.134.1 - - [15/Oct/1997:19:27:51 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-203.18.134.1 - - [15/Oct/1997:19:27:52 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-203.18.134.1 - - [15/Oct/1997:19:27:53 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-203.18.134.1 - - [15/Oct/1997:19:27:54 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-203.18.134.1 - - [15/Oct/1997:19:27:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-203.18.134.1 - - [15/Oct/1997:19:27:56 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-203.18.134.1 - - [15/Oct/1997:19:27:58 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-203.18.134.1 - - [15/Oct/1997:19:27:58 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-203.18.134.1 - - [15/Oct/1997:19:27:59 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-203.18.134.1 - - [15/Oct/1997:19:28:02 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-203.18.134.1 - - [15/Oct/1997:19:28:03 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-203.18.134.1 - - [15/Oct/1997:19:28:04 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-203.18.134.1 - - [15/Oct/1997:19:28:06 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-203.18.134.1 - - [15/Oct/1997:19:28:08 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-203.18.134.1 - - [15/Oct/1997:19:28:09 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-203.18.134.1 - - [15/Oct/1997:19:28:09 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-203.18.134.1 - - [15/Oct/1997:19:28:10 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-203.18.134.1 - - [15/Oct/1997:19:28:11 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-203.18.134.1 - - [15/Oct/1997:19:28:12 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-203.18.134.1 - - [15/Oct/1997:19:28:13 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-204.192.112.114 - - [15/Oct/1997:19:28:28 -0700] "GET /robots.txt HTTP/1.0" 404 163-204.192.112.114 - - [15/Oct/1997:19:28:29 -0700] "GET / HTTP/1.0" 200 3082-203.18.134.1 - - [15/Oct/1997:19:28:51 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629-203.18.134.1 - - [15/Oct/1997:19:28:54 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638-203.18.134.1 - - [15/Oct/1997:19:28:55 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785-203.18.134.1 - - [15/Oct/1997:19:28:57 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859-203.18.134.1 - - [15/Oct/1997:19:28:58 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237-203.18.134.1 - - [15/Oct/1997:19:28:59 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903-203.18.134.1 - - [15/Oct/1997:19:29:01 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833-203.18.134.1 - - [15/Oct/1997:19:29:01 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352-203.18.134.1 - - [15/Oct/1997:19:29:03 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836-203.18.134.1 - - [15/Oct/1997:19:29:06 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429-203.18.134.1 - - [15/Oct/1997:19:29:06 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625-203.18.134.1 - - [15/Oct/1997:19:29:14 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509-203.18.134.1 - - [15/Oct/1997:19:29:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-203.18.134.1 - - [15/Oct/1997:19:32:09 -0700] "GET /amnesty/guatem/ndsa.html HTTP/1.0" 200 2605-203.18.134.1 - - [15/Oct/1997:19:32:11 -0700] "GET /amnesty/guatem/magglas2.jpg HTTP/1.0" 200 798-203.18.134.1 - - [15/Oct/1997:19:32:11 -0700] "GET /amnesty/images/wordo35c.jpg HTTP/1.0" 200 4123-203.18.134.1 - - [15/Oct/1997:19:32:13 -0700] "GET /amnesty/images/wordoll2.jpg HTTP/1.0" 200 3063-203.18.134.1 - - [15/Oct/1997:19:33:30 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-203.18.134.1 - - [15/Oct/1997:19:33:30 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-203.18.134.1 - - [15/Oct/1997:19:33:32 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-203.18.134.1 - - [15/Oct/1997:19:33:34 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-203.18.134.1 - - [15/Oct/1997:19:33:34 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-203.18.134.1 - - [15/Oct/1997:19:33:35 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-203.18.134.1 - - [15/Oct/1997:19:33:36 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-203.18.134.1 - - [15/Oct/1997:19:33:37 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-203.18.134.1 - - [15/Oct/1997:19:33:39 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-203.18.134.1 - - [15/Oct/1997:19:33:40 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-203.18.134.1 - - [15/Oct/1997:19:33:41 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-203.18.134.1 - - [15/Oct/1997:19:33:42 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731-203.18.134.1 - - [15/Oct/1997:19:33:43 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-203.18.134.1 - - [15/Oct/1997:19:33:47 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882-203.18.134.1 - - [15/Oct/1997:19:33:48 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924-203.18.134.1 - - [15/Oct/1997:19:33:48 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914-203.18.134.1 - - [15/Oct/1997:19:33:49 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951-203.18.134.1 - - [15/Oct/1997:19:33:50 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190-203.18.134.1 - - [15/Oct/1997:19:33:51 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155-203.18.134.1 - - [15/Oct/1997:19:33:51 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938-203.18.134.1 - - [15/Oct/1997:19:33:52 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865-203.18.134.1 - - [15/Oct/1997:19:33:52 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946-203.18.134.1 - - [15/Oct/1997:19:33:53 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191-203.18.134.1 - - [15/Oct/1997:19:33:54 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170-203.18.134.1 - - [15/Oct/1997:19:33:55 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311-203.18.134.1 - - [15/Oct/1997:19:33:56 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786-203.18.134.1 - - [15/Oct/1997:19:33:57 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-203.18.134.1 - - [15/Oct/1997:19:33:58 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-203.18.134.1 - - [15/Oct/1997:19:33:58 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-203.18.134.1 - - [15/Oct/1997:19:33:59 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-203.18.134.1 - - [15/Oct/1997:19:34:00 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157-203.18.134.1 - - [15/Oct/1997:19:34:01 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-203.18.134.1 - - [15/Oct/1997:19:34:01 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-203.18.134.1 - - [15/Oct/1997:19:34:02 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591-203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 28581-203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-203.18.134.1 - - [15/Oct/1997:19:34:14 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-203.18.134.1 - - [15/Oct/1997:19:34:14 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-203.18.134.1 - - [15/Oct/1997:19:34:15 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-203.18.134.1 - - [15/Oct/1997:19:34:15 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-203.18.134.1 - - [15/Oct/1997:19:34:17 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-204.62.245.166 - - [15/Oct/1997:19:35:24 -0700] "GET /amnesty/guatem/uscondec.html HTTP/1.0" 200 3282-140.142.174.15 - - [15/Oct/1997:19:37:47 -0700] "GET /amnesty HTTP/1.0" 301 184-140.142.174.15 - - [15/Oct/1997:19:37:48 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-140.142.174.15 - - [15/Oct/1997:19:37:50 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-140.142.174.15 - - [15/Oct/1997:19:37:52 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-140.142.174.15 - - [15/Oct/1997:19:38:21 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-140.142.174.15 - - [15/Oct/1997:19:38:21 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-140.142.174.15 - - [15/Oct/1997:19:38:22 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-140.142.174.15 - - [15/Oct/1997:19:38:23 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-140.142.174.15 - - [15/Oct/1997:19:38:25 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-140.142.174.15 - - [15/Oct/1997:19:38:26 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-140.142.174.15 - - [15/Oct/1997:19:38:28 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-140.142.174.15 - - [15/Oct/1997:19:38:28 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-140.142.174.15 - - [15/Oct/1997:19:38:30 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-140.142.174.15 - - [15/Oct/1997:19:38:30 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889-140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482-140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849-140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447-140.142.174.15 - - [15/Oct/1997:19:38:34 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-140.142.174.15 - - [15/Oct/1997:19:38:34 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-207.137.47.247 - - [15/Oct/1997:19:38:35 -0700] "GET /amnesty/guatem/howdolls.html HTTP/1.0" 200 4203-207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow1.jpg HTTP/1.0" 200 2635-207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow2.jpg HTTP/1.0" 200 4865-207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow3.jpg HTTP/1.0" 200 7300-207.137.47.247 - - [15/Oct/1997:19:38:41 -0700] "GET /amnesty/images/wordoll2.jpg HTTP/1.0" 200 3063-140.142.174.15 - - [15/Oct/1997:19:38:54 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-140.142.174.15 - - [15/Oct/1997:19:38:55 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-140.142.174.15 - - [15/Oct/1997:19:38:55 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-140.142.174.15 - - [15/Oct/1997:19:38:59 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-207.137.47.247 - - [15/Oct/1997:19:39:03 -0700] "GET /amnesty/images/dollhow4.jpg HTTP/1.0" 200 10830-140.142.174.15 - - [15/Oct/1997:19:39:08 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-140.142.174.15 - - [15/Oct/1997:19:40:26 -0700] "GET /amnesty/country.html HTTP/1.0" 200 1765-140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/tools/topline3.gif HTTP/1.0" 200 233-140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/tools/topline4.gif HTTP/1.0" 200 263-140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-140.142.174.15 - - [15/Oct/1997:19:40:41 -0700] "GET /amnesty/country/index.html HTTP/1.0" 200 2808-140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/balkhead.jpg HTTP/1.0" 200 5046-140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/rwanhea2.gif HTTP/1.0" 200 2737-140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/topline4.gif HTTP/1.0" 200 263-140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-140.142.174.15 - - [15/Oct/1997:19:40:45 -0700] "GET /amnesty/country/images/nigeria3.gif HTTP/1.0" 200 1549-140.142.174.15 - - [15/Oct/1997:19:40:46 -0700] "GET /amnesty/country/images/topline3.gif HTTP/1.0" 200 233-140.142.174.15 - - [15/Oct/1997:19:40:55 -0700] "GET /amnesty/country/images/goddess3.jpg HTTP/1.0" 200 5491-140.142.174.15 - - [15/Oct/1997:19:40:56 -0700] "GET /amnesty/country/images/hrme2.jpg HTTP/1.0" 200 7337-140.142.174.15 - - [15/Oct/1997:19:40:56 -0700] "GET /amnesty/country/images/mandala2.jpg HTTP/1.0" 200 7568-32.96.68.164 - - [15/Oct/1997:19:41:08 -0700] "GET / HTTP/1.0" 200 3082-32.96.68.164 - - [15/Oct/1997:19:41:10 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-32.96.68.164 - - [15/Oct/1997:19:41:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-32.96.68.164 - - [15/Oct/1997:19:41:29 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-32.96.68.164 - - [15/Oct/1997:19:41:29 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-32.96.68.164 - - [15/Oct/1997:19:41:30 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-32.96.68.164 - - [15/Oct/1997:19:41:30 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-32.96.68.164 - - [15/Oct/1997:19:41:31 -0700] "GET /ainews.html HTTP/1.0" 200 13435-32.96.68.164 - - [15/Oct/1997:19:41:32 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-32.96.68.164 - - [15/Oct/1997:19:41:36 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-32.96.68.164 - - [15/Oct/1997:19:41:39 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-32.96.68.164 - - [15/Oct/1997:19:41:41 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-32.96.68.164 - - [15/Oct/1997:19:41:41 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-32.96.68.164 - - [15/Oct/1997:19:41:42 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-32.96.68.164 - - [15/Oct/1997:19:41:42 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-32.96.68.164 - - [15/Oct/1997:19:41:48 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-140.142.174.15 - - [15/Oct/1997:19:49:25 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-204.62.245.32 - - [15/Oct/1997:19:52:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-158.152.1.181 - - [15/Oct/1997:19:53:14 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-128.226.4.62 - - [15/Oct/1997:19:53:29 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-207.115.1.33 - - [15/Oct/1997:19:53:34 -0700] "GET / HTTP/1.0" 200 3082-128.226.4.62 - - [15/Oct/1997:19:53:35 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-128.226.4.62 - - [15/Oct/1997:19:53:35 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-207.115.1.33 - - [15/Oct/1997:19:53:36 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-207.115.1.33 - - [15/Oct/1997:19:53:37 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-128.226.4.62 - - [15/Oct/1997:19:53:47 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731-128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865-128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190-128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924-128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914-128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311-128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155-128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170-128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938-128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951-128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157-128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591-128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946-128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882-128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 28581-128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786-128.226.4.62 - - [15/Oct/1997:19:53:57 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191-128.226.4.62 - - [15/Oct/1997:19:54:12 -0700] "GET /amnesty/postcard/welact.html HTTP/1.0" 200 4640-128.226.4.62 - - [15/Oct/1997:19:54:17 -0700] "GET /amnesty/postcard/images/joinbut.gif HTTP/1.0" 200 409-128.226.4.62 - - [15/Oct/1997:19:54:17 -0700] "GET /amnesty/postcard/images/welbut.gif HTTP/1.0" 200 600-128.226.4.62 - - [15/Oct/1997:19:54:18 -0700] "GET /amnesty/postcard/images/aiusabut.gif HTTP/1.0" 200 591-128.226.4.62 - - [15/Oct/1997:19:54:18 -0700] "GET /amnesty/postcard/images/letbut.gif HTTP/1.0" 200 517-128.226.4.62 - - [15/Oct/1997:19:54:19 -0700] "GET /amnesty/postcard/images/w.gif HTTP/1.0" 200 565-128.226.4.62 - - [15/Oct/1997:19:54:20 -0700] "GET /amnesty/postcard/images/wombarb9.gif HTTP/1.0" 200 20647-207.115.1.33 - - [15/Oct/1997:19:54:34 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562-207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-207.115.1.33 - - [15/Oct/1997:19:54:41 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-128.226.4.62 - - [15/Oct/1997:19:54:45 -0700] "GET /amnesty/postcard/anyapp.html HTTP/1.0" 200 3797-128.226.4.62 - - [15/Oct/1997:19:54:46 -0700] "GET /amnesty/postcard/images/blkcnd2.gif HTTP/1.0" 200 1082-128.226.4.62 - - [15/Oct/1997:19:55:10 -0700] "GET /amnesty/postcard/anylett.html HTTP/1.0" 200 1489-207.115.1.33 - - [15/Oct/1997:19:56:16 -0700] "GET /asa/china/louisa-links.html HTTP/1.0" 200 1076-208.136.13.104 - - [15/Oct/1997:19:56:37 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-208.136.13.104 - - [15/Oct/1997:19:56:43 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-208.136.13.104 - - [15/Oct/1997:19:56:43 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-208.136.13.104 - - [15/Oct/1997:19:56:44 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-208.136.13.104 - - [15/Oct/1997:19:56:44 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-198.168.101.58 - - [15/Oct/1997:19:59:35 -0700] "GET / HTTP/1.0" 200 3082-198.168.101.58 - - [15/Oct/1997:19:59:37 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-198.168.101.58 - - [15/Oct/1997:19:59:39 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-128.226.4.62 - - [15/Oct/1997:20:00:03 -0700] "GET /amnesty/postcard/welgroup.html HTTP/1.0" 200 8002-128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/goldfla2.gif HTTP/1.0" 200 1161-128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/grncndl.gif HTTP/1.0" 200 1471-128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/weletbut.gif HTTP/1.0" 200 566-128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257-128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430-128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013-198.110.98.5 - - [15/Oct/1997:20:01:07 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-128.226.4.62 - - [15/Oct/1997:20:01:13 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-128.226.4.62 - - [15/Oct/1997:20:01:20 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-128.226.4.62 - - [15/Oct/1997:20:01:37 -0700] "GET /amnesty/ainews/china/execrec.html HTTP/1.0" 200 6897-204.74.108.98 - - [15/Oct/1997:20:01:39 -0700] "GET / HTTP/1.0" 200 3082-204.74.108.98 - - [15/Oct/1997:20:01:40 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-204.74.108.98 - - [15/Oct/1997:20:01:40 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-204.74.108.98 - - [15/Oct/1997:20:02:01 -0700] "GET /home.html HTTP/1.0" 200 17233-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-204.74.108.98 - - [15/Oct/1997:20:02:05 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-128.226.4.62 - - [15/Oct/1997:20:02:06 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-204.74.108.98 - - [15/Oct/1997:20:02:07 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-204.74.108.98 - - [15/Oct/1997:20:02:08 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-204.201.210.19 - - [15/Oct/1997:20:02:35 -0700] "GET /country/balkans HTTP/1.0" 301 196-204.201.210.19 - - [15/Oct/1997:20:02:36 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-204.201.210.19 - - [15/Oct/1997:20:02:39 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-204.74.108.98 - - [15/Oct/1997:20:04:05 -0700] "GET /candatop.html HTTP/1.0" 200 10629-204.74.108.98 - - [15/Oct/1997:20:04:06 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638-204.74.108.98 - - [15/Oct/1997:20:04:06 -0700] "GET /images/done.gif HTTP/1.0" 200 4785-204.74.108.98 - - [15/Oct/1997:20:04:07 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833-204.74.108.98 - - [15/Oct/1997:20:04:07 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625-204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-204.74.108.98 - - [15/Oct/1997:20:04:09 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-204.74.108.98 - - [15/Oct/1997:20:04:09 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-204.74.108.98 - - [15/Oct/1997:20:05:17 -0700] "GET /talun.html HTTP/1.0" 200 1210-204.74.108.98 - - [15/Oct/1997:20:05:31 -0700] "GET /reyes.html HTTP/1.0" 200 2137-204.74.108.98 - - [15/Oct/1997:20:05:32 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-204.74.108.98 - - [15/Oct/1997:20:05:46 -0700] "GET /turkoglu.html HTTP/1.0" 200 1176-204.201.210.19 - - [15/Oct/1997:20:05:47 -0700] "GET /country/index.html HTTP/1.0" 200 2808-204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/balkhead.jpg HTTP/1.0" 200 5046-204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/rwanhea2.gif HTTP/1.0" 200 2737-204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/topline4.gif HTTP/1.0" 200 263-204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-204.201.210.19 - - [15/Oct/1997:20:05:52 -0700] "GET /country/images/nigeria3.gif HTTP/1.0" 200 1549-204.201.210.19 - - [15/Oct/1997:20:05:57 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 200 7568-204.201.210.19 - - [15/Oct/1997:20:05:57 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-204.201.210.19 - - [15/Oct/1997:20:05:59 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-204.201.210.19 - - [15/Oct/1997:20:05:59 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-204.201.210.19 - - [15/Oct/1997:20:06:01 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491-204.74.108.98 - - [15/Oct/1997:20:06:02 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-204.74.108.98 - - [15/Oct/1997:20:06:02 -0700] "GET /joinai.html HTTP/1.0" 200 4054-204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491-204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 200 7337-204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/topline3.gif HTTP/1.0" 200 233-204.201.210.19 - - [15/Oct/1997:20:06:34 -0700] "GET /country/rwanda/index.html HTTP/1.0" 200 1987-204.201.210.19 - - [15/Oct/1997:20:06:36 -0700] "GET /country/rwanda/images/rwanbg.jpg HTTP/1.0" 200 4042-204.201.210.19 - - [15/Oct/1997:20:06:36 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-204.201.210.19 - - [15/Oct/1997:20:06:45 -0700] "GET /country/rwanda/images/rwanhead.gif HTTP/1.0" 200 20639-209.12.153.58 - - [15/Oct/1997:20:07:06 -0700] "GET /amnesty/women/index.html HTTP/1.0" 200 8198-209.12.153.58 - - [15/Oct/1997:20:07:07 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-204.74.108.98 - - [15/Oct/1997:20:07:08 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-209.12.153.58 - - [15/Oct/1997:20:07:24 -0700] "GET /amnesty/women/images/unocal3.gif HTTP/1.0" 200 1170-209.12.153.58 - - [15/Oct/1997:20:07:30 -0700] "GET /amnesty/women/images/enronlog.gif HTTP/1.0" 200 17130-209.12.153.58 - - [15/Oct/1997:20:07:45 -0700] "GET /amnesty/women/images/sari1.gif HTTP/1.0" 200 1784-209.12.153.58 - - [15/Oct/1997:20:07:46 -0700] "GET /amnesty/women/images/afgref2.jpg HTTP/1.0" 200 3853-209.12.153.58 - - [15/Oct/1997:20:07:46 -0700] "GET /amnesty/women/images/afwom5.jpg HTTP/1.0" 200 3853-209.12.153.58 - - [15/Oct/1997:20:07:48 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575-204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-204.201.210.19 - - [15/Oct/1997:20:07:58 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 206 4709-204.201.210.19 - - [15/Oct/1997:20:07:58 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 6555-204.201.210.19 - - [15/Oct/1997:20:07:59 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 5250-204.201.210.19 - - [15/Oct/1997:20:08:00 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --209.12.153.58 - - [15/Oct/1997:20:08:01 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-209.12.153.58 - - [15/Oct/1997:20:08:03 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-209.12.153.58 - - [15/Oct/1997:20:08:04 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-209.12.153.58 - - [15/Oct/1997:20:08:06 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-209.12.153.58 - - [15/Oct/1997:20:08:07 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161-209.12.153.58 - - [15/Oct/1997:20:08:07 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471-209.12.153.58 - - [15/Oct/1997:20:08:09 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-209.12.153.58 - - [15/Oct/1997:20:08:15 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-209.12.153.58 - - [15/Oct/1997:20:08:21 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013-209.12.153.58 - - [15/Oct/1997:20:08:36 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430-204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 206 3954-204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 5800-204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 4496-204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /images/newbutx.gif HTTP/1.0" 206 930-204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /images/amnty1.gif HTTP/1.0" 200 3013-204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /images/nigeria2.gif HTTP/1.0" 200 2518-204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /nigsham.html HTTP/1.0" 200 19559-204.201.210.19 - - [15/Oct/1997:20:09:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.201.210.19 - - [15/Oct/1997:20:09:08 -0700] "GET /images/chris.jpg HTTP/1.0" 200 8302-204.201.210.19 - - [15/Oct/1997:20:09:08 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-209.12.153.58 - - [15/Oct/1997:20:09:10 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399-204.201.210.19 - - [15/Oct/1997:20:09:11 -0700] "GET /images/image1.jpg HTTP/1.0" 200 8557-209.12.153.58 - - [15/Oct/1997:20:09:12 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257-204.201.210.19 - - [15/Oct/1997:20:09:13 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-204.201.210.19 - - [15/Oct/1997:20:09:13 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-204.201.210.19 - - [15/Oct/1997:20:09:15 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-204.201.210.19 - - [15/Oct/1997:20:09:39 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 1462-204.201.210.19 - - [15/Oct/1997:20:09:39 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 1694-204.201.210.19 - - [15/Oct/1997:20:09:40 -0700] "GET /images/aboutbux.gif HTTP/1.0" 206 850-209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/afgref2.jpg HTTP/1.0" 304 --209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/afwom5.jpg HTTP/1.0" 304 --209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/sari1.gif HTTP/1.0" 200 1784-146.6.94.50 - - [15/Oct/1997:20:10:07 -0700] "GET / HTTP/1.0" 200 3082-146.6.94.50 - - [15/Oct/1997:20:10:17 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-146.6.94.50 - - [15/Oct/1997:20:10:21 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-38.14.126.160 - - [15/Oct/1997:20:11:51 -0700] "GET / HTTP/1.0" 200 3082-38.14.126.160 - - [15/Oct/1997:20:11:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-38.14.126.160 - - [15/Oct/1997:20:11:53 -0700] "GET /images/spot5.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:08 -0700] "GET /country HTTP/1.0" 301 188-38.14.126.160 - - [15/Oct/1997:20:12:08 -0700] "GET /country/ HTTP/1.0" 200 2808-38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/balkhead.jpg HTTP/1.0" 200 5046-38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/rwanhea2.gif HTTP/1.0" 200 2737-38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/topline4.gif HTTP/1.0" 200 263-38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:12 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 200 7568-38.14.126.160 - - [15/Oct/1997:20:12:12 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:15 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491-38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 200 7337-38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:23 -0700] "GET /country/images/nigeria3.gif HTTP/1.0" 200 1549-38.14.126.160 - - [15/Oct/1997:20:12:23 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:28 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --38.14.126.160 - - [15/Oct/1997:20:12:31 -0700] "GET /country/images/topline3.gif HTTP/1.0" 200 233-206.86.247.122 - - [15/Oct/1997:20:16:38 -0700] "GET /usalinks.html HTTP/1.0" 200 10329-206.86.247.122 - - [15/Oct/1997:20:16:44 -0700] "GET /amnesty/fw.html HTTP/1.0" 200 779-203.116.1.245 - - [15/Oct/1997:20:16:52 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-192.65.17.24 - - [15/Oct/1997:20:20:26 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-192.65.17.24 - - [15/Oct/1997:20:20:31 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-192.65.17.24 - - [15/Oct/1997:20:20:33 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-192.65.17.24 - - [15/Oct/1997:20:20:56 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-192.65.17.24 - - [15/Oct/1997:20:21:08 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-192.65.17.24 - - [15/Oct/1997:20:23:40 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-192.65.17.24 - - [15/Oct/1997:20:23:49 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-192.65.17.24 - - [15/Oct/1997:20:23:49 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-192.65.17.24 - - [15/Oct/1997:20:23:50 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-192.65.17.24 - - [15/Oct/1997:20:23:56 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-192.65.17.24 - - [15/Oct/1997:20:23:56 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889-192.65.17.24 - - [15/Oct/1997:20:23:57 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482-192.65.17.24 - - [15/Oct/1997:20:23:57 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447-192.65.17.24 - - [15/Oct/1997:20:23:59 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849-192.65.17.24 - - [15/Oct/1997:20:24:02 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-192.65.17.24 - - [15/Oct/1997:20:24:03 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-38.14.126.160 - - [15/Oct/1997:20:24:07 -0700] "GET /country/balkans HTTP/1.0" 301 196-38.14.126.160 - - [15/Oct/1997:20:24:08 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-38.14.126.160 - - [15/Oct/1997:20:24:11 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-38.14.126.160 - - [15/Oct/1997:20:24:12 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-38.14.126.160 - - [15/Oct/1997:20:24:12 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-38.14.126.160 - - [15/Oct/1997:20:24:13 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-38.14.126.160 - - [15/Oct/1997:20:24:16 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-192.65.17.24 - - [15/Oct/1997:20:24:33 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-192.65.17.24 - - [15/Oct/1997:20:24:36 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-192.65.17.24 - - [15/Oct/1997:20:24:37 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-192.65.17.24 - - [15/Oct/1997:20:24:37 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-192.65.17.24 - - [15/Oct/1997:20:24:46 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-192.65.17.24 - - [15/Oct/1997:20:24:46 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-192.65.17.24 - - [15/Oct/1997:20:24:47 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-192.65.17.24 - - [15/Oct/1997:20:24:52 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-192.65.17.24 - - [15/Oct/1997:20:24:56 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-192.65.17.24 - - [15/Oct/1997:20:24:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-192.65.17.24 - - [15/Oct/1997:20:24:57 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-192.65.17.24 - - [15/Oct/1997:20:24:58 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-192.65.17.24 - - [15/Oct/1997:20:24:58 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-192.65.17.24 - - [15/Oct/1997:20:24:59 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-192.65.17.24 - - [15/Oct/1997:20:24:59 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-192.65.17.24 - - [15/Oct/1997:20:25:00 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-192.65.17.24 - - [15/Oct/1997:20:25:09 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-192.65.17.24 - - [15/Oct/1997:20:25:14 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-192.65.17.24 - - [15/Oct/1997:20:25:37 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283-192.65.17.24 - - [15/Oct/1997:20:25:41 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-192.65.17.24 - - [15/Oct/1997:20:25:45 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-192.65.17.24 - - [15/Oct/1997:20:25:45 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-192.65.17.24 - - [15/Oct/1997:20:25:47 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-192.65.17.24 - - [15/Oct/1997:20:27:22 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074-192.65.17.24 - - [15/Oct/1997:20:27:23 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43-132.254.40.136 - - [15/Oct/1997:20:30:29 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-132.254.40.136 - - [15/Oct/1997:20:30:32 -0700] "GET /amnesty/latinam/spoeadp.html HTTP/1.0" 200 8540-128.8.21.79 - - [15/Oct/1997:20:34:34 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-128.8.21.79 - - [15/Oct/1997:20:34:37 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-128.8.21.79 - - [15/Oct/1997:20:34:42 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-128.8.21.79 - - [15/Oct/1997:20:34:46 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-128.8.21.79 - - [15/Oct/1997:20:35:04 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-128.8.21.79 - - [15/Oct/1997:20:35:04 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-128.8.21.79 - - [15/Oct/1997:20:35:05 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-128.8.21.79 - - [15/Oct/1997:20:35:05 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-128.8.21.79 - - [15/Oct/1997:20:35:10 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-128.8.21.79 - - [15/Oct/1997:20:35:10 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-128.8.21.79 - - [15/Oct/1997:20:35:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-128.8.21.79 - - [15/Oct/1997:20:35:17 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-128.8.21.79 - - [15/Oct/1997:20:35:20 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-128.8.21.79 - - [15/Oct/1997:20:35:24 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-128.8.21.79 - - [15/Oct/1997:20:35:27 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-128.8.21.79 - - [15/Oct/1997:20:35:27 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-128.8.21.79 - - [15/Oct/1997:20:35:28 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-128.8.21.79 - - [15/Oct/1997:20:35:29 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-128.8.21.79 - - [15/Oct/1997:20:35:30 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-128.8.21.79 - - [15/Oct/1997:20:35:48 -0700] "GET /amnesty/country.html HTTP/1.0" 200 1765-128.8.21.79 - - [15/Oct/1997:20:35:50 -0700] "GET /amnesty/tools/topline4.gif HTTP/1.0" 200 263-128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/tools/topline3.gif HTTP/1.0" 200 233-128.8.21.79 - - [15/Oct/1997:20:35:52 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-128.8.21.79 - - [15/Oct/1997:20:35:53 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-128.8.21.79 - - [15/Oct/1997:20:35:54 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-128.8.21.79 - - [15/Oct/1997:20:35:55 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-204.162.96.93 - - [15/Oct/1997:20:35:57 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292-128.8.21.79 - - [15/Oct/1997:20:36:07 -0700] "GET /amnesty/country/index.html HTTP/1.0" 200 2808-128.8.21.79 - - [15/Oct/1997:20:36:09 -0700] "GET /amnesty/country/images/topline4.gif HTTP/1.0" 200 263-128.8.21.79 - - [15/Oct/1997:20:36:09 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-128.8.21.79 - - [15/Oct/1997:20:36:10 -0700] "GET /amnesty/country/images/balkhead.jpg HTTP/1.0" 200 5046-128.8.21.79 - - [15/Oct/1997:20:36:10 -0700] "GET /amnesty/country/images/rwanhea2.gif HTTP/1.0" 200 2737-128.8.21.79 - - [15/Oct/1997:20:36:13 -0700] "GET /amnesty/country/images/goddess3.jpg HTTP/1.0" 200 5491-128.8.21.79 - - [15/Oct/1997:20:36:14 -0700] "GET /amnesty/country/images/nigeria3.gif HTTP/1.0" 200 1549-128.8.21.79 - - [15/Oct/1997:20:36:18 -0700] "GET /amnesty/country/images/hrme2.jpg HTTP/1.0" 200 7337-128.8.21.79 - - [15/Oct/1997:20:36:22 -0700] "GET /amnesty/country/images/mandala2.jpg HTTP/1.0" 200 7568-128.8.21.79 - - [15/Oct/1997:20:36:25 -0700] "GET /amnesty/country/images/topline3.gif HTTP/1.0" 200 233-128.8.21.79 - - [15/Oct/1997:20:36:54 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629-128.8.21.79 - - [15/Oct/1997:20:36:55 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785-128.8.21.79 - - [15/Oct/1997:20:36:56 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237-128.8.21.79 - - [15/Oct/1997:20:37:03 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638-128.8.21.79 - - [15/Oct/1997:20:37:04 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352-128.8.21.79 - - [15/Oct/1997:20:37:06 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859-polux.entelchile.net - - [15/Oct/1997:21:02:07 -0700] "GET /latinam/spoeadp.html HTTP/1.0" 200 8540-polux.entelchile.net - - [15/Oct/1997:21:02:29 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-ws186.library.msstate.edu - - [15/Oct/1997:21:02:44 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292-ws186.library.msstate.edu - - [15/Oct/1997:21:02:45 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:02:49 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:09 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:09 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:10 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:15 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:17 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:17 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:04:58 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:10 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:16 -0700] "GET /amnesty/urgact HTTP/1.0" 301 191-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:18 -0700] "GET /amnesty/urgact/ HTTP/1.0" 200 8283-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:33 -0700] "GET /amnesty/urgact/uafaq.html HTTP/1.0" 200 20157-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:55 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:56 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166-1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:58 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179-ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:07 -0700] "GET /amnesty HTTP/1.0" 301 184-ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:09 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:12 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:17 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-polux.entelchile.net - - [15/Oct/1997:21:08:38 -0700] "GET /ainews.html HTTP/1.0" 200 13435-polux.entelchile.net - - [15/Oct/1997:21:08:44 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-polux.entelchile.net - - [15/Oct/1997:21:09:01 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-polux.entelchile.net - - [15/Oct/1997:21:09:10 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-polux.entelchile.net - - [15/Oct/1997:21:09:10 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-polux.entelchile.net - - [15/Oct/1997:21:09:23 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:33 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:35 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:36 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:37 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:13:59 -0700] "GET / HTTP/1.0" 200 3082-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:01 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:03 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:23 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:31 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:31 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:32 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:34 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:34 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:35 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:36 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:39 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:41 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:47 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:49 -0700] "GET /group.html HTTP/1.0" 200 8575-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:57 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:15:00 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:15:09 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:14 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:18 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:22 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:33 -0700] "GET /urgact/index.html HTTP/1.0" 200 8283-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:36 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:37 -0700] "GET /index.html HTTP/1.0" 200 3082-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:40 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:42 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:58 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:31 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:35 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:35 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:34 -0700] "GET /about.html HTTP/1.0" 200 6902-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:36 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:37 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/where.gif HTTP/1.0" 200 605-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:39 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:39 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:40 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:11 -0700] "GET /group.html HTTP/1.0" 200 8575-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399-proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:21 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430-ppp23.fortworth.dfw.net - - [15/Oct/1997:22:04:57 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-al-jacob.wvmccd.cc.ca.us - - [15/Oct/1997:22:05:24 -0700] "GET / HTTP/1.0" 200 3082-proxy4.la.prodigy.net - - [15/Oct/1997:22:05:26 -0700] "GET /casework/index.html HTTP/1.0" 304 --proxy4.la.prodigy.net - - [15/Oct/1997:22:05:27 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-proxy4.la.prodigy.net - - [15/Oct/1997:22:05:29 -0700] "GET /casework/index.html HTTP/1.0" 304 --proxy4.la.prodigy.net - - [15/Oct/1997:22:05:30 -0700] "GET /casework/index.html HTTP/1.0" 304 --proxy4.la.prodigy.net - - [15/Oct/1997:22:05:32 -0700] "GET /casework/index.html HTTP/1.0" 304 --wdcsun2.usdoj.gov - - [15/Oct/1997:22:05:58 -0700] "GET /amnesty/women/afghaii.html HTTP/1.0" 200 3854-ip051029.dialup.wvnet.edu - - [15/Oct/1997:22:10:45 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178-globulus.itd.uts.edu.au - - [15/Oct/1997:22:14:51 -0700] "GET /women/enronbac.html HTTP/1.0" 200 6806-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:02 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:05 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:05 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:11 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:12 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:25 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:01 -0700] "GET / HTTP/1.0" 200 3082-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:15 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:16 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:45 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:49 -0700] "GET /joinai.html HTTP/1.0" 200 4054-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:51 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:53 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:53 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:54 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:54 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:22:02 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:25:05 -0700] "GET /joinai.txt HTTP/1.0" 200 1914-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:28:46 -0700] "GET /home.html HTTP/1.0" 200 3854-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:28:59 -0700] "GET /home.html HTTP/1.0" 200 17233-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:03 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:03 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:05 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:06 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:07 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:12 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:13 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:13 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:14 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:18 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:18 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:19 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:19 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-templeton-bbn.infoseek.com - - [15/Oct/1997:22:53:53 -0700] "GET /robots.txt HTTP/1.0" 404 163-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:53:56 -0700] "GET / HTTP/1.0" 200 3082-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-slip166-72-240-91.oh.us.ibm.net - - [15/Oct/1997:22:54:15 -0700] "GET / HTTP/1.0" 200 3082-slip166-72-240-91.oh.us.ibm.net - - [15/Oct/1997:22:54:17 -0700] "GET /amnesty/usalinks.html HTTP/1.0" 200 3854-templeton-bbn.infoseek.com - - [15/Oct/1997:22:54:17 -0700] "GET /asa/china/ HTTP/1.0" 200 3854-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:19 -0700] "GET /welcome.html HTTP/1.0" 200 4731-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:21 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:22 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:22 -0700] "GET /images/never.gif HTTP/1.0" 200 914-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:25 -0700] "GET /images/a.gif HTTP/1.0" 200 865-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:26 -0700] "GET /images/commit.gif HTTP/1.0" 200 190-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:26 -0700] "GET /images/rights.gif HTTP/1.0" 200 938-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:28 -0700] "GET /images/canred.gif HTTP/1.0" 200 311-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:32 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:33 -0700] "GET /images/human.gif HTTP/1.0" 200 155-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:33 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:34 -0700] "GET /images/differ.gif HTTP/1.0" 200 191-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:36 -0700] "GET /images/your.gif HTTP/1.0" 200 951-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:37 -0700] "GET /images/can.gif HTTP/1.0" 200 946-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:37 -0700] "GET /images/it.gif HTTP/1.0" 200 170-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:40 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157-ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:43 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581-ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-piweba5y-ext.prodigy.com - - [15/Oct/1997:23:00:34 -0700] "GET / HTTP/1.0" 200 3082-146.7.214.63 - - [15/Oct/1997:23:04:37 -0700] "GET /comm/stewart.html HTTP/1.0" 200 1648-146.7.214.63 - - [15/Oct/1997:23:04:46 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517-146.7.214.63 - - [15/Oct/1997:23:04:52 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43-146.7.214.63 - - [15/Oct/1997:23:04:54 -0700] "GET /comm/images/people/stew4.jpg HTTP/1.0" 200 11278-templeton-bbn.infoseek.com - - [15/Oct/1997:23:31:38 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902-ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:45:48 -0700] "GET /whatsnew.html** HTTP/1.0" 404 168-ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:10 -0700] "GET /whatsnew.html** HTTP/1.0" 404 168-ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:32 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562-ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/homenew.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --j8.inktomi.com - - [15/Oct/1997:23:47:57 -0700] "GET /education HTTP/1.0" 301 190-pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:09 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-galore-bbn.infoseek.com - - [16/Oct/1997:00:35:46 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:36 -0700] "GET /urgact/ HTTP/1.0" 200 8283-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-203.21.39.23 - - [16/Oct/1997:00:57:21 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:49 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:51 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:51 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:53 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-widow.av.pa-x.dec.com - - [16/Oct/1997:01:18:00 -0700] "GET /amnesty/so-cal.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:01:19:14 -0700] "GET /amnesty/index.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:01:21:40 -0700] "GET /amnesty/guatem/iobdecl.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:01:25:45 -0700] "GET /amnesty/guatem/ndsa4.html HTTP/1.0" 304 --md18-228.mun.compuserve.com - - [16/Oct/1997:01:33:20 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-templeton-bbn.infoseek.com - - [16/Oct/1997:01:35:20 -0700] "GET /amnesty/regions/maregcon.html HTTP/1.0" 304 --templeton-bbn.infoseek.com - - [16/Oct/1997:01:37:42 -0700] "GET /robots.txt HTTP/1.0" 404 163-templeton-bbn.infoseek.com - - [16/Oct/1997:01:37:52 -0700] "GET /education/ HTTP/1.0" 200 --lsc070067.res-hall.nwu.edu - - [16/Oct/1997:01:40:55 -0700] "GET /amnesty/regions/startrek.html HTTP/1.0" 404 182-px1.syd.aone.net.au - - [16/Oct/1997:01:45:47 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-px1.syd.aone.net.au - - [16/Oct/1997:01:45:48 -0700] "GET /feats/coptrain.html HTTP/1.0" 200 20726-widow.av.pa-x.dec.com - - [16/Oct/1997:01:48:43 -0700] "GET /amnesty/guatem/ngodcl.html HTTP/1.0" 304 --stargate.uni-paderborn.de - - [16/Oct/1997:01:50:47 -0700] "GET / HTTP/1.0" 200 3082-stargate.uni-paderborn.de - - [16/Oct/1997:01:50:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-stargate.uni-paderborn.de - - [16/Oct/1997:01:50:52 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:04 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:04 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:05 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:06 -0700] "GET /home.html HTTP/1.0" 200 17233-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:06 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:07 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:08 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:10 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:11 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:14 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:15 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:15 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:16 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:18 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:23 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:26 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:27 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:29 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:30 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:32 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-stargate.uni-paderborn.de - - [16/Oct/1997:01:51:33 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-widow.av.pa-x.dec.com - - [16/Oct/1997:01:51:48 -0700] "GET /amnesty/guatem/huelgade.html HTTP/1.0" 304 --stargate.uni-paderborn.de - - [16/Oct/1997:01:51:53 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-aluminum.elemental.ultra.net.au - - [16/Oct/1997:02:00:52 -0700] "GET /images/suu50b.jpg HTTP/1.0" 200 17237-aluminum.elemental.ultra.net.au - - [16/Oct/1997:02:00:52 -0700] "GET /myanmar/aungsan.html HTTP/1.0" 200 14464-widow.av.pa-x.dec.com - - [16/Oct/1997:02:02:43 -0700] "GET /amnesty/guatem/guatcamp.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:02:04:50 -0700] "GET /amnesty/guatem/guatdc.html HTTP/1.0" 304 --ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:51 -0700] "GET /amnesty HTTP/1.0" 301 184-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:52 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:54 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:57 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:12 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-barracuda.res.wpi.net - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:17 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:18 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:18 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:21 -0700] "GET /asa/china/ HTTP/1.1" 200 18000-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:21 -0700] "GET /asa/china/contents.html HTTP/1.1" 200 3336-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:29 -0700] "GET /asa/china/chinese.html HTTP/1.1" 200 15983-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:32 -0700] "GET /asa/china/images/welcome.gif HTTP/1.1" 200 1049-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:37 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.1" 200 27794-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:42 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:42 -0700] "GET /asa/china/images/hk.gif HTTP/1.1" 200 1212-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:46 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:46 -0700] "GET /asa/china/images/tibet.gif HTTP/1.1" 200 1241-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:47 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.1" 200 36122-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:50 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.1" 200 4196-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:50 -0700] "GET /asa/china/images/xj.gif HTTP/1.1" 200 1247-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:53 -0700] "GET /asa/china/images/link.gif HTTP/1.1" 200 4236-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:55 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.1" 200 2899-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:55 -0700] "GET /asa/china/images/renquan.gif HTTP/1.1" 200 411-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:56 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.1" 200 3648-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:56 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.1" 200 1202-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:59 -0700] "GET /asa/china/images/aichico.gif HTTP/1.1" 200 4724-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:03 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.1" 200 17344-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:04 -0700] "GET /asa/china/images/animai.gif HTTP/1.1" 200 5175-1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:05 -0700] "GET /asa/china/images/smflag.gif HTTP/1.1" 200 951-ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:08:44 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:41 -0700] "GET / HTTP/1.0" 200 3082-ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:43 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:44 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-widow.av.pa-x.dec.com - - [16/Oct/1997:02:14:00 -0700] "GET /amnesty/guatem/uscondec.html HTTP/1.0" 304 --lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:41 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534-lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/amnty1.gif HTTP/1.0" 200 3013-lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/back.gif HTTP/1.0" 200 224-lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/clear.gif HTTP/1.0" 200 76-gk-red.unicc.org - - [16/Oct/1997:02:15:54 -0700] "GET / HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:17:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:17:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:17:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:17:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:17:16 -0700] "GET / HTTP/1.0" 200 3082-dialup74-3-48.swipnet.se - - [16/Oct/1997:02:17:58 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:02:18:01 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-dialup74-3-48.swipnet.se - - [16/Oct/1997:02:18:01 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-dialup74-3-48.swipnet.se - - [16/Oct/1997:02:18:03 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-dialup74-3-48.swipnet.se - - [16/Oct/1997:02:19:48 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-dialup74-3-48.swipnet.se - - [16/Oct/1997:02:24:38 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-obatanga.chat.carleton.ca - - [16/Oct/1997:02:26:06 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178-142.los-angeles-09.ca.dial-access.att.net - - [16/Oct/1997:02:37:00 -0700] "GET /home.html HTTP/1.0" 200 17233-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:22 -0700] "GET /i-what.html HTTP/1.0" 404 164-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:42 -0700] "GET / HTTP/1.0" 200 3082-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:45 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:46 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:57 -0700] "GET /about.html HTTP/1.0" 200 6902-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:03 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:04 -0700] "GET /images/where.gif HTTP/1.0" 200 605-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:43 -0700] "GET /about/history.html HTTP/1.0" 200 10342-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:45 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:45 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:46 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:47 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:47 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:48 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:48 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:45:13 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-gymnasiet-4.hanko.fi - - [16/Oct/1997:02:45:23 -0700] "GET /i-what.html HTTP/1.0" 404 164-194.158.162.143 - - [16/Oct/1997:02:50:22 -0700] "GET /country/balkans HTTP/1.0" 301 196-194.158.162.143 - - [16/Oct/1997:02:50:23 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-194.158.162.143 - - [16/Oct/1997:02:50:27 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-194.158.162.143 - - [16/Oct/1997:02:50:27 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188-194.158.162.143 - - [16/Oct/1997:02:50:29 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-194.158.162.143 - - [16/Oct/1997:02:50:33 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-194.158.162.143 - - [16/Oct/1997:02:50:33 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188-194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-194.158.162.143 - - [16/Oct/1997:02:50:37 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188-194.158.162.143 - - [16/Oct/1997:02:50:37 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-195.53.57.2 - - [16/Oct/1997:02:53:15 -0700] "GET /latinam/spoeadp.html HTTP/1.0" 200 8540-195.53.57.2 - - [16/Oct/1997:02:53:20 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-widow.av.pa-x.dec.com - - [16/Oct/1997:02:53:28 -0700] "GET /amnesty/guatem/guatdocs.html HTTP/1.0" 304 --194.158.162.143 - - [16/Oct/1997:02:54:10 -0700] "GET /country/balkans HTTP/1.0" 301 196-194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /home.html HTTP/1.0" 200 17233-194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-194.158.162.143 - - [16/Oct/1997:02:54:57 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-194.158.162.143 - - [16/Oct/1997:02:55:00 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-194.158.162.143 - - [16/Oct/1997:02:55:01 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-194.158.162.143 - - [16/Oct/1997:02:55:01 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-194.158.162.143 - - [16/Oct/1997:02:55:02 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-194.158.162.143 - - [16/Oct/1997:02:55:09 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-194.158.162.143 - - [16/Oct/1997:02:55:10 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-194.158.162.143 - - [16/Oct/1997:02:55:14 -0700] "GET /ainews.html HTTP/1.0" 200 13435-194.158.162.143 - - [16/Oct/1997:02:55:15 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-194.158.162.143 - - [16/Oct/1997:02:55:15 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-194.158.162.143 - - [16/Oct/1997:02:55:16 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-194.158.162.143 - - [16/Oct/1997:02:55:17 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-194.158.162.143 - - [16/Oct/1997:02:55:17 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-194.158.162.143 - - [16/Oct/1997:02:55:18 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-194.158.162.143 - - [16/Oct/1997:02:55:20 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-194.158.162.143 - - [16/Oct/1997:02:56:03 -0700] "GET /ainews/cuba/criticsp.html HTTP/1.0" 200 7711-194.158.162.143 - - [16/Oct/1997:02:56:04 -0700] "GET /ainews/images/blkcnd2.gif HTTP/1.0" 200 1082-194.158.162.143 - - [16/Oct/1997:02:56:12 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-widow.av.pa-x.dec.com - - [16/Oct/1997:03:02:49 -0700] "GET /amnesty/guatem/aidecl.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:03:18:20 -0700] "GET /amnesty/guatem/guatacts.html HTTP/1.0" 304 --widow.av.pa-x.dec.com - - [16/Oct/1997:03:27:46 -0700] "GET /amnesty/guatem/bgdecl.html HTTP/1.0" 304 --ppp066.b.ite.net - - [16/Oct/1997:03:36:06 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ppp066.b.ite.net - - [16/Oct/1997:03:36:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ppp066.b.ite.net - - [16/Oct/1997:03:36:12 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ppp066.b.ite.net - - [16/Oct/1997:03:37:04 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902-ppp066.b.ite.net - - [16/Oct/1997:03:37:06 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509-ppp066.b.ite.net - - [16/Oct/1997:03:37:07 -0700] "GET /amnesty/images/whobut.gif HTTP/1.0" 200 505-ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/whatbut.gif HTTP/1.0" 200 526-ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/where.gif HTTP/1.0" 200 605-ppp066.b.ite.net - - [16/Oct/1997:03:37:17 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/aalogo.gif HTTP/1.0" 200 15293-ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-ppp066.b.ite.net - - [16/Oct/1997:03:37:22 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-ppp066.b.ite.net - - [16/Oct/1997:03:38:33 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785-ppp066.b.ite.net - - [16/Oct/1997:03:38:34 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629-ppp066.b.ite.net - - [16/Oct/1997:03:38:48 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638-ppp066.b.ite.net - - [16/Oct/1997:03:38:50 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859-ppp066.b.ite.net - - [16/Oct/1997:03:38:56 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903-ppp066.b.ite.net - - [16/Oct/1997:03:38:56 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237-ppp066.b.ite.net - - [16/Oct/1997:03:38:58 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836-ppp066.b.ite.net - - [16/Oct/1997:03:39:03 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833-ppp066.b.ite.net - - [16/Oct/1997:03:39:08 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429-ppp066.b.ite.net - - [16/Oct/1997:03:39:08 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-ppp066.b.ite.net - - [16/Oct/1997:03:39:09 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625-ppp066.b.ite.net - - [16/Oct/1997:03:39:14 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352-ppp066.b.ite.net - - [16/Oct/1997:03:39:20 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-ppp066.b.ite.net - - [16/Oct/1997:03:39:23 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-ppp066.b.ite.net - - [16/Oct/1997:03:40:09 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:42:31 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:42:34 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-widow.av.pa-x.dec.com - - [16/Oct/1997:03:42:40 -0700] "GET /amnesty/guatem/guatstud.html HTTP/1.0" 304 --proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:06 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:10 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:10 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:11 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:14 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:15 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:18 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:19 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:21 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:22 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-141.244.102.33 - - [16/Oct/1997:03:57:32 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-141.244.102.33 - - [16/Oct/1997:03:59:17 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855-141.244.102.33 - - [16/Oct/1997:03:59:30 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855-141.244.102.33 - - [16/Oct/1997:03:59:43 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855-202.231.192.180 - - [16/Oct/1997:04:09:02 -0700] "GET /usalinks.html HTTP/1.0" 200 10329-202.231.192.180 - - [16/Oct/1997:04:09:05 -0700] "GET /images/ai_cand1.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:05 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:12 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --202.231.192.180 - - [16/Oct/1997:04:09:12 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43-hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074-hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-hud02a01.ml.com - - [16/Oct/1997:04:23:03 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:03 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812-hud02a01.ml.com - - [16/Oct/1997:04:23:04 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:23:06 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 --203.8.223.2 - - [16/Oct/1997:04:23:54 -0700] "GET /amnesty/feats/china1.html HTTP/1.0" 200 3303-203.8.223.2 - - [16/Oct/1997:04:24:10 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:34 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/images/linebrn.gif HTTP/1.0" 200 308-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/weeklyua.html HTTP/1.0" 200 10887-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:32 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:32 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-proxyf11.cyberway.com.sg - - [16/Oct/1997:04:30:45 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-hud02a01.ml.com - - [16/Oct/1997:04:32:30 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:30 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-hud02a01.ml.com - - [16/Oct/1997:04:32:32 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074-hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-hud02a01.ml.com - - [16/Oct/1997:04:32:34 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812-hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 --202.54.52.100 - - [16/Oct/1997:04:39:23 -0700] "GET /amnesty/immigr.html HTTP/1.0" 200 11284-poppy.mcc.ac.uk - - [16/Oct/1997:04:39:29 -0700] "GET /asa/china/ HTTP/1.0" 200 18000-poppy.mcc.ac.uk - - [16/Oct/1997:04:41:03 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336-poppy.mcc.ac.uk - - [16/Oct/1997:04:42:08 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951-poppy.mcc.ac.uk - - [16/Oct/1997:04:42:18 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 200 5175-poppy.mcc.ac.uk - - [16/Oct/1997:04:42:21 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983-widow.av.pa-x.dec.com - - [16/Oct/1997:04:42:49 -0700] "GET /amnesty/guatem/howdolls.html HTTP/1.0" 304 --poppy.mcc.ac.uk - - [16/Oct/1997:04:43:15 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-poppy.mcc.ac.uk - - [16/Oct/1997:04:43:15 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196-poppy.mcc.ac.uk - - [16/Oct/1997:04:44:14 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241-poppy.mcc.ac.uk - - [16/Oct/1997:04:44:28 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247-poppy.mcc.ac.uk - - [16/Oct/1997:04:45:10 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724-poppy.mcc.ac.uk - - [16/Oct/1997:04:46:10 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049-poppy.mcc.ac.uk - - [16/Oct/1997:04:46:48 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899-palo10.pacific.net.sg - - [16/Oct/1997:04:48:08 -0700] "GET / HTTP/1.0" 200 3082-poppy.mcc.ac.uk - - [16/Oct/1997:04:49:04 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236-poppy.mcc.ac.uk - - [16/Oct/1997:04:49:15 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 16384-poppy.mcc.ac.uk - - [16/Oct/1997:04:49:29 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 206 2114-palo10.pacific.net.sg - - [16/Oct/1997:04:49:46 -0700] "GET /ainews.html HTTP/1.0" 200 13435-poppy.mcc.ac.uk - - [16/Oct/1997:04:50:04 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 206 19844-poppy.mcc.ac.uk - - [16/Oct/1997:04:50:58 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411-poppy.mcc.ac.uk - - [16/Oct/1997:04:51:03 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344-palo10.pacific.net.sg - - [16/Oct/1997:04:51:10 -0700] "GET /ainews/singapore/sue.html HTTP/1.0" 200 5225-poppy.mcc.ac.uk - - [16/Oct/1997:04:51:45 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202-poppy.mcc.ac.uk - - [16/Oct/1997:04:51:54 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 9487-poppy.mcc.ac.uk - - [16/Oct/1997:04:52:47 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 304 --poppy.mcc.ac.uk - - [16/Oct/1997:04:52:58 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 206 30731-palo10.pacific.net.sg - - [16/Oct/1997:04:53:23 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-poppy.mcc.ac.uk - - [16/Oct/1997:04:54:46 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 206 11441-ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:10 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:38 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:38 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:39 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:39 -0700] "GET /amnesty/images/turqbut.gif HTTP/1.0" 200 903-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:42 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:48 -0700] "GET /amnesty/refugee/refqa.html HTTP/1.0" 200 18657-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/morinfox.gif HTTP/1.0" 200 2056-pc5249.cmiu.bt.co.uk - - [16/Oct/1997:05:14:20 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534-194.184.94.45 - - [16/Oct/1997:05:15:30 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-204.232.49.4 - - [16/Oct/1997:05:15:32 -0700] "GET / HTTP/1.0" 200 3082-204.232.49.4 - - [16/Oct/1997:05:15:39 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-204.232.49.4 - - [16/Oct/1997:05:15:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-206.23.223.136 - - [16/Oct/1997:05:16:05 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178-rolf.powersim.no - - [16/Oct/1997:05:16:28 -0700] "GET /spanish/images/yi.gif HTTP/1.0" 200 16599-193.213.14.50 - - [16/Oct/1997:05:16:29 -0700] "GET /spanish/fwspupda.html HTTP/1.0" 200 4283-rolf.powersim.no - - [16/Oct/1997:05:16:30 -0700] "GET /spanish/images/padilla2.gif HTTP/1.0" 200 12312-rolf.powersim.no - - [16/Oct/1997:05:16:31 -0700] "GET /spanish/images/ghaleh.gif HTTP/1.0" 200 27250-pc26.huron.ac.uk - - [16/Oct/1997:05:17:43 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-204.232.49.4 - - [16/Oct/1997:05:21:44 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-204.232.49.4 - - [16/Oct/1997:05:21:44 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-204.232.49.4 - - [16/Oct/1997:05:21:45 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-204.232.49.4 - - [16/Oct/1997:05:21:46 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-204.232.49.4 - - [16/Oct/1997:05:21:54 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-204.232.49.4 - - [16/Oct/1997:05:21:55 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-204.232.49.4 - - [16/Oct/1997:05:21:57 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-204.232.49.4 - - [16/Oct/1997:05:21:57 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-204.232.49.4 - - [16/Oct/1997:05:21:58 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-204.232.49.4 - - [16/Oct/1997:05:21:59 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-204.232.49.4 - - [16/Oct/1997:05:22:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.232.49.4 - - [16/Oct/1997:05:22:03 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-204.232.49.4 - - [16/Oct/1997:05:22:07 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-204.232.49.4 - - [16/Oct/1997:05:22:07 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-204.232.49.4 - - [16/Oct/1997:05:22:11 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-204.232.49.4 - - [16/Oct/1997:05:22:12 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-204.232.49.4 - - [16/Oct/1997:05:22:15 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-204.232.49.4 - - [16/Oct/1997:05:22:16 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-204.232.49.4 - - [16/Oct/1997:05:22:17 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-204.232.49.4 - - [16/Oct/1997:05:22:19 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-ircf.funet.fi - - [16/Oct/1997:05:26:47 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-hhtam025027.netvigator.com - - [16/Oct/1997:05:29:57 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-207.38.218.70 - - [16/Oct/1997:05:30:56 -0700] "GET /ainews.html HTTP/1.0" 304 --hhtam025027.netvigator.com - - [16/Oct/1997:05:30:56 -0700] "GET /asa/china/consdoc.html HTTP/1.0" 200 32768-207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /images/refhand4.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 3854-207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:09 -0700] "GET / HTTP/1.0" 200 3082-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:11 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:15 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:38 -0700] "GET /amnesty/asa/china/images/animai.gif HTTP/1.0" 200 5175-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:39 -0700] "GET /amnesty/asa/china/images/smflag.gif HTTP/1.0" 200 951-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:44 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:44 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:45 -0700] "GET /amnesty/asa/china/chinese.html HTTP/1.0" 200 15983-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/hk.gif HTTP/1.0" 200 1212-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/mail8380.gif HTTP/1.0" 200 4196-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/tibet.gif HTTP/1.0" 200 1241-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/xj.gif HTTP/1.0" 200 1247-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:48 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:48 -0700] "GET /amnesty/asa/china/images/aichico.gif HTTP/1.0" 200 4724-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:51 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:51 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:58 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:58 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:59 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:59 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:02 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:06 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:32:09 -0700] "GET /amnesty/asa/china/images/mailbox1.gif HTTP/1.0" 200 17344-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:09 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:10 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:11 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:15 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:15 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:21 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:27 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:30 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:38 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-207.38.218.70 - - [16/Oct/1997:05:32:39 -0700] "GET /ainews.html HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:43 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-207.38.218.70 - - [16/Oct/1997:05:32:44 -0700] "GET /images/homebut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:44 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/countbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/joinbut.gif HTTP/1.0" 304 --207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/netbut.gif HTTP/1.0" 304 --pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:23 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:23 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:27 -0700] "GET /ainews.html HTTP/1.0" 200 13435-pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:27 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:31 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 8192-198.215.121.135 - - [16/Oct/1997:05:37:18 -0700] "GET /asa/china/ HTTP/1.0" 200 18000-198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983-198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336-198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 200 5175-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241-198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247-198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724-198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122-198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247-198.215.121.135 - - [16/Oct/1997:05:37:22 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899-198.215.121.135 - - [16/Oct/1997:05:37:22 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236-198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196-198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344-198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648-198.215.121.135 - - [16/Oct/1997:05:37:24 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202-198.215.121.135 - - [16/Oct/1997:05:37:26 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:46:47 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:46:48 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:02 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 3855-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:15 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:21 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:23 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:23 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:34 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 3854-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:27 -0700] "GET /amnesty/home.html HTTP/1.0" 200 3854-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:27 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 3854-pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:48:31 -0700] "GET /amnesty/pakistan/viol.html HTTP/1.0" 200 7679-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:48:34 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-198.108.140.121 - - [16/Oct/1997:05:50:41 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292-198.108.140.121 - - [16/Oct/1997:05:50:42 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-mso94.marsweb.com - - [16/Oct/1997:05:51:27 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:48 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:48 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:52 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:52 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:55 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:00 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:19 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 3855-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:23 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:25 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:28 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:29 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:31 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:32 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:33 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:36 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:52:37 -0700] "GET /amnesty/urgact/contact.html HTTP/1.0" 200 882-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:38 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-hhtam005082.netvigator.com - - [16/Oct/1997:05:52:41 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-207.38.218.89 - - [16/Oct/1997:05:52:42 -0700] "GET / HTTP/1.0" 200 --207.38.218.89 - - [16/Oct/1997:05:52:44 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-207.38.218.89 - - [16/Oct/1997:05:52:44 -0700] "GET /images/spot5.gif HTTP/1.0" 304 --hhtam005082.netvigator.com - - [16/Oct/1997:05:52:45 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 8192-hhtam005082.netvigator.com - - [16/Oct/1997:05:53:13 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 304 --hhtam005082.netvigator.com - - [16/Oct/1997:05:53:14 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-hhtam005082.netvigator.com - - [16/Oct/1997:05:53:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-hhtam005082.netvigator.com - - [16/Oct/1997:05:53:15 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 304 --s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-hhtam005082.netvigator.com - - [16/Oct/1997:05:53:18 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 206 6029-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:21 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:21 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:22 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:24 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:25 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:25 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:26 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:26 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:27 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:27 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:28 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:31 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:47 -0700] "GET /amnesty/members.html HTTP/1.0" 200 1501-s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:49 -0700] "GET /amnesty/images/memlogo.gif HTTP/1.0" 200 7872-ehv51-2.eindhoven.nl.net - - [16/Oct/1997:06:00:03 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:10 -0700] "GET /country/balkans HTTP/1.0" 301 196-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:18 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:28 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:28 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:29 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:30 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:30 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:54 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:54 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:55 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354-ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:55 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:06 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:10 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:11 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:18 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:21 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:43 -0700] "GET /amnesty/ainews/usa/texas.html HTTP/1.0" 200 5825-ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:45 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:19 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:22 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:22 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:24 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:24 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:26 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:27 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:32 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:33 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:34 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:38 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:43 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:44 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:45 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122-spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:52 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344-208.195.7.217 - - [16/Oct/1997:06:08:32 -0700] "GET / HTTP/1.0" 200 3082-208.195.7.217 - - [16/Oct/1997:06:08:36 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-208.195.7.217 - - [16/Oct/1997:06:08:36 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-208.195.7.217 - - [16/Oct/1997:06:08:57 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-208.195.7.217 - - [16/Oct/1997:06:08:59 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-208.195.7.217 - - [16/Oct/1997:06:08:59 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-208.195.7.217 - - [16/Oct/1997:06:09:00 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-208.195.7.217 - - [16/Oct/1997:06:09:05 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-208.195.7.217 - - [16/Oct/1997:06:09:05 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-208.195.7.217 - - [16/Oct/1997:06:09:06 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-208.195.7.217 - - [16/Oct/1997:06:09:06 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-208.195.7.217 - - [16/Oct/1997:06:09:07 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-208.195.7.217 - - [16/Oct/1997:06:09:10 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-208.195.7.217 - - [16/Oct/1997:06:09:11 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-208.195.7.217 - - [16/Oct/1997:06:09:14 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-208.195.7.217 - - [16/Oct/1997:06:09:14 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-208.195.7.217 - - [16/Oct/1997:06:09:16 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-208.195.7.217 - - [16/Oct/1997:06:09:16 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-208.195.7.217 - - [16/Oct/1997:06:09:18 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-208.195.7.217 - - [16/Oct/1997:06:09:45 -0700] "GET /casework/index.html HTTP/1.0" 200 2974-208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/aiusarex.gif HTTP/1.0" 200 3237-208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-208.195.7.217 - - [16/Oct/1997:06:09:50 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 200 8650-208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-208.195.7.217 - - [16/Oct/1997:06:09:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-208.195.7.217 - - [16/Oct/1997:06:10:12 -0700] "GET /casework/fw.html HTTP/1.0" 200 5528-208.195.7.217 - - [16/Oct/1997:06:10:18 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 200 1158-208.195.7.217 - - [16/Oct/1997:06:10:18 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 200 10003-208.195.7.217 - - [16/Oct/1997:06:11:51 -0700] "GET /casework/fw1.html HTTP/1.0" 200 2813-199.250.191.4 - - [16/Oct/1997:06:14:38 -0700] "GET /urgact/ HTTP/1.0" 200 8283-ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:46 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:48 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:49 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:49 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-spg-tnt12s127.erols.com - - [16/Oct/1997:06:21:24 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:28 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:30 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:38 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562-207.38.218.77 - - [16/Oct/1997:06:23:09 -0700] "GET /images/ai_cand1.gif HTTP/1.0" 200 6328-207.38.218.77 - - [16/Oct/1997:06:23:09 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-207.38.218.77 - - [16/Oct/1997:06:23:12 -0700] "GET /usalinks.html HTTP/1.0" 200 10329-207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-207.38.218.77 - - [16/Oct/1997:06:23:15 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-207.38.218.77 - - [16/Oct/1997:06:23:15 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-207.38.218.77 - - [16/Oct/1997:06:23:37 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-207.38.218.77 - - [16/Oct/1997:06:23:37 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-207.38.218.77 - - [16/Oct/1997:06:23:38 -0700] "GET /home.html HTTP/1.0" 200 17233-207.38.218.77 - - [16/Oct/1997:06:23:40 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-207.38.218.77 - - [16/Oct/1997:06:23:40 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-207.38.218.77 - - [16/Oct/1997:06:23:41 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-207.38.218.77 - - [16/Oct/1997:06:23:42 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-207.38.218.77 - - [16/Oct/1997:06:23:42 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-207.38.218.77 - - [16/Oct/1997:06:23:44 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-207.38.218.77 - - [16/Oct/1997:06:23:44 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /ainews.html HTTP/1.0" 200 13435-207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-207.38.218.77 - - [16/Oct/1997:06:23:48 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-207.38.218.77 - - [16/Oct/1997:06:23:48 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-207.38.218.77 - - [16/Oct/1997:06:23:49 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-207.38.218.77 - - [16/Oct/1997:06:23:50 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-207.38.218.77 - - [16/Oct/1997:06:23:51 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 8192-207.38.218.77 - - [16/Oct/1997:06:23:52 -0700] "GET /ainews/israel_occupied_territories/killing.html HTTP/1.0" 200 6647-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:07 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:09 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:14 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:17 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:18 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:24 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:25 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:33 -0700] "GET /amnesty/asa/china/louisa-links.html HTTP/1.0" 200 1076-hud02a01.ml.com - - [16/Oct/1997:06:26:23 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:24 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074-hud02a01.ml.com - - [16/Oct/1997:06:26:25 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:25 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-hud02a01.ml.com - - [16/Oct/1997:06:26:27 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-hud02a01.ml.com - - [16/Oct/1997:06:26:31 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:31 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812-hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:33 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 --hud02a01.ml.com - - [16/Oct/1997:06:26:36 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 --spg-tnt12s127.erols.com - - [16/Oct/1997:06:27:11 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-spg-tnt12s127.erols.com - - [16/Oct/1997:06:27:48 -0700] "GET /amnesty/asa/china/chadrel-newsflash.html HTTP/1.0" 200 1084-spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:00 -0700] "GET /amnesty/asa/china/images/c_chinma.jpg HTTP/1.0" 200 4655-proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:00 -0700] "GET /casework/index.html HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/aiusarex.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:05 -0700] "GET /amnesty/asa/china/images/newsflas.gif HTTP/1.0" 200 2340-proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:14 -0700] "GET /casework/fw.html HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:16 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 304 --proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:16 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 304 --spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:31 -0700] "GET /amnesty/asa/china/images/chadrel.jpg HTTP/1.0" 200 20391-proxy1.ykt.prodigy.net - - [16/Oct/1997:06:29:11 -0700] "GET /casework/fw1.html HTTP/1.0" 304 --spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:35 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:43 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:44 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:47 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:48 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:51 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:54 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:55 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:58 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:09 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:33 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:35 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:46 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:53 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:54 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:55 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:09 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:37 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:41 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-proxy1.ykt.prodigy.net - - [16/Oct/1997:06:31:41 -0700] "GET /casework/fw2.html HTTP/1.0" 304 --spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:49 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:55 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:02 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:06 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:08 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:09 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:14 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-194.151.13.64 - - [16/Oct/1997:06:33:36 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-spg-tnt12s127.erols.com - - [16/Oct/1997:06:33:37 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283-193.63.139.50 - - [16/Oct/1997:06:34:03 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-gk-red.unicc.org - - [16/Oct/1997:06:34:29 -0700] "GET /amnesty/mideast/libya.html HTTP/1.0" 200 6278-gk-red.unicc.org - - [16/Oct/1997:06:34:36 -0700] "GET /amnesty/mideast/libya.jpg HTTP/1.0" 200 4641-gk-red.unicc.org - - [16/Oct/1997:06:34:39 -0700] "GET /amnesty/mideast/libflag.gif HTTP/1.0" 200 1364-gk-red.unicc.org - - [16/Oct/1997:06:34:41 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202-spg-tnt12s127.erols.com - - [16/Oct/1997:06:35:46 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283-spg-tnt12s127.erols.com - - [16/Oct/1997:06:35:48 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-131.123.15.27 - - [16/Oct/1997:06:35:54 -0700] "GET /images/aiusa2.gif HTTP/1.0" 200 2905-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:36:26 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178-krafla.rhi.hi.is - - [16/Oct/1997:06:36:29 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-krafla.rhi.hi.is - - [16/Oct/1997:06:36:30 -0700] "GET /amnesty/about/history.html HTTP/1.0" 200 10342-krafla.rhi.hi.is - - [16/Oct/1997:06:38:41 -0700] "GET /amnesty/about/images/masthd3.gif HTTP/1.0" 200 33250-130inf121.cinet.es - - [16/Oct/1997:06:38:47 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-130inf121.cinet.es - - [16/Oct/1997:06:39:15 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-130inf121.cinet.es - - [16/Oct/1997:06:39:37 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/hometake.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/writbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:38 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:38 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:39 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:39 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:40 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/homenew.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/homeside.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:45 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:47 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:48 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:48 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/countbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/savebutx.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/spanbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:50 -0700] "GET /images/getbut.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:39:50 -0700] "GET /images/membutx.gif HTTP/1.0" 304 --130inf121.cinet.es - - [16/Oct/1997:06:40:13 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-dialup177-1-5.swipnet.se - - [16/Oct/1997:06:41:32 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329-146.186.150.185 - - [16/Oct/1997:06:45:20 -0700] "GET / HTTP/1.0" 200 3082-146.186.150.185 - - [16/Oct/1997:06:45:21 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-146.186.150.185 - - [16/Oct/1997:06:45:21 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-146.186.150.185 - - [16/Oct/1997:06:45:45 -0700] "GET /about.html HTTP/1.0" 200 6902-146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-146.186.150.185 - - [16/Oct/1997:06:45:47 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-146.186.150.185 - - [16/Oct/1997:06:45:47 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-146.186.150.185 - - [16/Oct/1997:06:45:48 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-146.186.150.185 - - [16/Oct/1997:06:45:52 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-146.186.150.185 - - [16/Oct/1997:06:45:53 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-146.186.150.185 - - [16/Oct/1997:06:45:54 -0700] "GET /images/where.gif HTTP/1.0" 200 605-palo1.pacific.net.sg - - [16/Oct/1997:06:45:57 -0700] "GET /amnesty HTTP/1.0" 301 184-palo1.pacific.net.sg - - [16/Oct/1997:06:45:59 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-palo1.pacific.net.sg - - [16/Oct/1997:06:46:03 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /group.html HTTP/1.0" 200 8575-146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161-146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471-146.186.150.185 - - [16/Oct/1997:06:46:22 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013-146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257-146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-146.186.150.185 - - [16/Oct/1997:06:46:24 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-palo1.pacific.net.sg - - [16/Oct/1997:06:46:25 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435-146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399-146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-146.186.150.185 - - [16/Oct/1997:06:46:28 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430-palo1.pacific.net.sg - - [16/Oct/1997:06:46:32 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189-palo1.pacific.net.sg - - [16/Oct/1997:06:46:32 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-palo1.pacific.net.sg - - [16/Oct/1997:06:46:33 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448-palo1.pacific.net.sg - - [16/Oct/1997:06:46:40 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427-palo1.pacific.net.sg - - [16/Oct/1997:06:46:42 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789-palo1.pacific.net.sg - - [16/Oct/1997:06:46:48 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-palo1.pacific.net.sg - - [16/Oct/1997:06:46:51 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-146.186.150.185 - - [16/Oct/1997:06:46:54 -0700] "GET /ann-rpt.html HTTP/1.0" 200 1899-146.186.150.185 - - [16/Oct/1997:06:46:55 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-146.186.150.185 - - [16/Oct/1997:06:46:55 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-146.186.150.185 - - [16/Oct/1997:06:47:02 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-146.186.150.185 - - [16/Oct/1997:06:47:06 -0700] "GET /ar-sum.html HTTP/1.0" 200 27608-ppp44.igc.org - - [16/Oct/1997:06:47:08 -0700] "GET /regions/west.html HTTP/1.0" 200 5900-palo1.pacific.net.sg - - [16/Oct/1997:06:47:10 -0700] "GET /amnesty/ainews/singapore/sue.html HTTP/1.0" 200 5225-ppp44.igc.org - - [16/Oct/1997:06:47:10 -0700] "GET /images/bg.gif HTTP/1.0" 200 2464-ppp44.igc.org - - [16/Oct/1997:06:47:11 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 --ppp44.igc.org - - [16/Oct/1997:06:47:13 -0700] "GET /images/refuges1.jpg HTTP/1.0" 200 7377-ppp44.igc.org - - [16/Oct/1997:06:47:16 -0700] "GET /images/border15.jpg HTTP/1.0" 200 5092-gate2.bankerstrust.com - - [16/Oct/1997:06:47:38 -0700] "GET /comm/jagger.html HTTP/1.0" 200 1864-gate2.bankerstrust.com - - [16/Oct/1997:06:47:44 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43-gate2.bankerstrust.com - - [16/Oct/1997:06:47:46 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517-gate2.bankerstrust.com - - [16/Oct/1997:06:47:46 -0700] "GET /comm/images/people/jagger4.jpg HTTP/1.0" 200 10112-gate2.bankerstrust.com - - [16/Oct/1997:06:48:18 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483-docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:21 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:22 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-gate2.bankerstrust.com - - [16/Oct/1997:06:48:27 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498-gate2.bankerstrust.com - - [16/Oct/1997:06:48:27 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-gate2.bankerstrust.com - - [16/Oct/1997:06:48:28 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848-gate2.bankerstrust.com - - [16/Oct/1997:06:48:33 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585-gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-gate2.bankerstrust.com - - [16/Oct/1997:06:48:41 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43-ppp44.igc.org - - [16/Oct/1997:06:49:12 -0700] "GET /regions/southern.html HTTP/1.0" 200 6455-palo1.pacific.net.sg - - [16/Oct/1997:06:49:13 -0700] "GET /amnesty/weeklyua.html HTTP/1.0" 200 10887-ppp44.igc.org - - [16/Oct/1997:06:49:15 -0700] "GET /regions/aiusared.gif HTTP/1.0" 200 2725-palo1.pacific.net.sg - - [16/Oct/1997:06:49:19 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343-palo1.pacific.net.sg - - [16/Oct/1997:06:49:22 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-palo1.pacific.net.sg - - [16/Oct/1997:06:49:22 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-palo1.pacific.net.sg - - [16/Oct/1997:06:49:31 -0700] "GET /amnesty/images/linebrn.gif HTTP/1.0" 200 308-palo1.pacific.net.sg - - [16/Oct/1997:06:49:45 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-palo1.pacific.net.sg - - [16/Oct/1997:06:49:57 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-palo1.pacific.net.sg - - [16/Oct/1997:06:50:07 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-docrefoff5.library.emory.edu - - [16/Oct/1997:06:50:09 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-gate2.bankerstrust.com - - [16/Oct/1997:06:53:00 -0700] "GET /ainews/usa/spotward.html HTTP/1.0" 200 7907-gate2.bankerstrust.com - - [16/Oct/1997:06:53:12 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-ppp2200.stk.inreach.net - - [16/Oct/1997:06:54:21 -0700] "GET /cambodia/prosecut.html HTTP/1.0" 200 4764-1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:23 -0700] "GET /amnesty/turkey/back.gif HTTP/1.0" 200 224-1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:24 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534-1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:27 -0700] "GET /amnesty/turkey/amnty1.gif HTTP/1.0" 200 3013-1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:27 -0700] "GET /amnesty/turkey/clear.gif HTTP/1.0" 200 76-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:57:33 -0700] "GET /amnesty/mideast/ HTTP/1.0" 200 3104-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:58:57 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:59:10 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682-194.165.130.7 - - [16/Oct/1997:06:59:34 -0700] "GET /amnesty/gan.html HTTP/1.0" 200 5020-194.165.130.7 - - [16/Oct/1997:06:59:39 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-194.165.130.7 - - [16/Oct/1997:06:59:39 -0700] "GET /amnesty/images/clear1.jpg HTTP/1.0" 200 849-194.165.130.7 - - [16/Oct/1997:06:59:43 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-194.165.130.7 - - [16/Oct/1997:06:59:47 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-194.165.130.7 - - [16/Oct/1997:07:00:19 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-194.165.130.7 - - [16/Oct/1997:07:00:20 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:00:20 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202-194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-194.165.130.7 - - [16/Oct/1997:07:00:31 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-194.165.130.7 - - [16/Oct/1997:07:00:33 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-194.165.130.7 - - [16/Oct/1997:07:00:35 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-194.165.130.7 - - [16/Oct/1997:07:00:37 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-194.165.130.7 - - [16/Oct/1997:07:00:37 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-194.165.130.7 - - [16/Oct/1997:07:00:40 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-194.165.130.7 - - [16/Oct/1997:07:00:42 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-194.165.130.7 - - [16/Oct/1997:07:00:43 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-194.165.130.7 - - [16/Oct/1997:07:00:45 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-194.165.130.7 - - [16/Oct/1997:07:00:54 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-ppp14.igc.org - - [16/Oct/1997:07:00:59 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-ppp14.igc.org - - [16/Oct/1997:07:00:59 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543-ppp14.igc.org - - [16/Oct/1997:07:01:01 -0700] "GET /home.html HTTP/1.0" 200 17233-194.165.130.7 - - [16/Oct/1997:07:01:05 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-194.165.130.7 - - [16/Oct/1997:07:01:06 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-ppp14.igc.org - - [16/Oct/1997:07:01:06 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 3854-194.165.130.7 - - [16/Oct/1997:07:01:08 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-194.165.130.7 - - [16/Oct/1997:07:01:12 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-194.165.130.7 - - [16/Oct/1997:07:01:12 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:27 -0700] "GET /amnesty/mideast/counfram.html HTTP/1.0" 200 1145-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:58 -0700] "GET /amnesty/mideast/algeria.html HTTP/1.0" 200 7945-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:59 -0700] "GET /amnesty/mideast/algflag.gif HTTP/1.0" 200 1902-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:05 -0700] "GET /amnesty/mideast/algeria.jpg HTTP/1.0" 200 5485-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:10 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:11 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:21 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:30 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:30 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:31 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:32 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:34 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:34 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:35 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:35 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:04:19 -0700] "GET /amnesty/mideast/saudi.jpg HTTP/1.0" 200 8769-ppp14.igc.org - - [16/Oct/1997:07:04:48 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304-ppp14.igc.org - - [16/Oct/1997:07:04:51 -0700] "GET /images/picasso.gif HTTP/1.0" 200 1213-ppp14.igc.org - - [16/Oct/1997:07:04:55 -0700] "GET /images/women05.jpg HTTP/1.0" 200 10130-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:04:56 -0700] "GET /amnesty/mideast/sauflag.gif HTTP/1.0" 200 3101-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:07:33 -0700] "GET /amnesty/mideast/saudi.html HTTP/1.0" 200 8072-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:14:56 -0700] "GET /amnesty/mideast/oman.jpg HTTP/1.0" 200 4371-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:14 -0700] "GET /amnesty/mideast/omanflag.gif HTTP/1.0" 200 2012-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:22 -0700] "GET /amnesty/mideast/gulf.html HTTP/1.0" 200 10736-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:23 -0700] "GET /amnesty/mideast/qatflag.gif HTTP/1.0" 200 1456-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:28 -0700] "GET /amnesty/mideast/qatar.jpg HTTP/1.0" 200 4615-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:29 -0700] "GET /amnesty/mideast/uaeflag.gif HTTP/1.0" 200 1725-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:42 -0700] "GET /amnesty/mideast/uae.jpg HTTP/1.0" 200 13752-168.30.243.210 - - [16/Oct/1997:07:18:52 -0700] "GET /amnesty/asa/china/images/animai.gif HTTP/1.0" 200 5175-168.30.243.210 - - [16/Oct/1997:07:18:52 -0700] "GET /amnesty/asa/china/images/smflag.gif HTTP/1.0" 200 951-168.30.243.210 - - [16/Oct/1997:07:18:53 -0700] "GET /amnesty/asa/china/chinese.html HTTP/1.0" 200 15983-168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/mail8380.gif HTTP/1.0" 200 4196-168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/tibet.gif HTTP/1.0" 200 1241-168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/xj.gif HTTP/1.0" 200 1247-168.30.243.210 - - [16/Oct/1997:07:18:55 -0700] "GET /amnesty/asa/china/images/aichico.gif HTTP/1.0" 200 4724-168.30.243.210 - - [16/Oct/1997:07:18:55 -0700] "GET /amnesty/asa/china/images/hk.gif HTTP/1.0" 200 1212-168.30.243.210 - - [16/Oct/1997:07:18:56 -0700] "GET /amnesty/asa/china/images/mailbox1.gif HTTP/1.0" 200 17344-ppp6-12.igc.org - - [16/Oct/1997:07:19:27 -0700] "GET / HTTP/1.0" 200 3082-ppp6-12.igc.org - - [16/Oct/1997:07:19:28 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-ppp6-12.igc.org - - [16/Oct/1997:07:19:40 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:22:01 -0700] "GET /amnesty/mideast/uaemona.html HTTP/1.0" 200 2200-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:22:59 -0700] "GET /amnesty/mideast/bahrain.html HTTP/1.0" 200 11354-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:23:01 -0700] "GET /amnesty/mideast/bahflag.gif HTTP/1.0" 200 1505-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:23:01 -0700] "GET /amnesty/mideast/bahrain.jpg HTTP/1.0" 200 5547-tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:24:13 -0700] "GET /amnesty/mideast/region.html HTTP/1.0" 200 1049-ppp22.igc.org - - [16/Oct/1997:07:27:23 -0700] "GET / HTTP/1.0" 200 3082-ppp22.igc.org - - [16/Oct/1997:07:27:26 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-ppp22.igc.org - - [16/Oct/1997:07:27:29 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ppp22.igc.org - - [16/Oct/1997:07:27:39 -0700] "GET /joinai.html HTTP/1.0" 200 4054-ppp22.igc.org - - [16/Oct/1997:07:27:41 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-ppp22.igc.org - - [16/Oct/1997:07:27:41 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-ppp22.igc.org - - [16/Oct/1997:07:27:42 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-ppp22.igc.org - - [16/Oct/1997:07:27:42 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-ppp22.igc.org - - [16/Oct/1997:07:27:44 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-ppp22.igc.org - - [16/Oct/1997:07:27:44 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-ppp22.igc.org - - [16/Oct/1997:07:28:12 -0700] "GET /amnesty HTTP/1.0" 301 184-ppp22.igc.org - - [16/Oct/1997:07:28:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ppp22.igc.org - - [16/Oct/1997:07:28:17 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ppp22.igc.org - - [16/Oct/1997:07:28:20 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ppp22.igc.org - - [16/Oct/1997:07:29:36 -0700] "GET /welcome.html HTTP/1.0" 200 4731-ppp22.igc.org - - [16/Oct/1997:07:29:39 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-ppp22.igc.org - - [16/Oct/1997:07:29:39 -0700] "GET /images/never.gif HTTP/1.0" 200 914-ppp22.igc.org - - [16/Oct/1997:07:29:41 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924-ppp22.igc.org - - [16/Oct/1997:07:29:43 -0700] "GET /images/your.gif HTTP/1.0" 200 951-ppp22.igc.org - - [16/Oct/1997:07:29:44 -0700] "GET /images/commit.gif HTTP/1.0" 200 190-ppp22.igc.org - - [16/Oct/1997:07:29:46 -0700] "GET /images/human.gif HTTP/1.0" 200 155-ppp22.igc.org - - [16/Oct/1997:07:29:46 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882-ppp22.igc.org - - [16/Oct/1997:07:29:48 -0700] "GET /images/can.gif HTTP/1.0" 200 946-ppp22.igc.org - - [16/Oct/1997:07:29:48 -0700] "GET /images/rights.gif HTTP/1.0" 200 938-ppp22.igc.org - - [16/Oct/1997:07:29:49 -0700] "GET /images/a.gif HTTP/1.0" 200 865-ppp22.igc.org - - [16/Oct/1997:07:29:49 -0700] "GET /images/differ.gif HTTP/1.0" 200 191-ppp22.igc.org - - [16/Oct/1997:07:29:50 -0700] "GET /images/it.gif HTTP/1.0" 200 170-ppp22.igc.org - - [16/Oct/1997:07:29:51 -0700] "GET /images/canred.gif HTTP/1.0" 200 311-ppp22.igc.org - - [16/Oct/1997:07:29:52 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-ppp22.igc.org - - [16/Oct/1997:07:29:54 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157-ppp22.igc.org - - [16/Oct/1997:07:29:57 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-ppp22.igc.org - - [16/Oct/1997:07:29:58 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591-ppp22.igc.org - - [16/Oct/1997:07:30:05 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:56 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:57 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:58 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:06 -0700] "GET /amnesty/comm/medaward.html HTTP/1.0" 200 6483-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/comm/images/starblu.jpg HTTP/1.0" 200 5498-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:10 -0700] "GET /amnesty/comm/images/bluai.jpg HTTP/1.0" 200 11848-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:10 -0700] "GET /amnesty/comm/images/bluspots.jpg HTTP/1.0" 200 18585-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:37 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:37 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:38 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:38 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:43 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-pm3-138.lex.infi.net - - [16/Oct/1997:07:38:19 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-pm3-138.lex.infi.net - - [16/Oct/1997:07:38:25 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-pm3-138.lex.infi.net - - [16/Oct/1997:07:38:27 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-pm3-138.lex.infi.net - - [16/Oct/1997:07:38:53 -0700] "GET /amnesty/images/usstamp.gif HTTP/1.0" 200 6166-pm3-138.lex.infi.net - - [16/Oct/1997:07:38:53 -0700] "GET /amnesty/write.html HTTP/1.0" 200 9408-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:01 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:03 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-pm3-138.lex.infi.net - - [16/Oct/1997:07:39:03 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:40:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-pm3-138.lex.infi.net - - [16/Oct/1997:07:40:37 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-pm3-138.lex.infi.net - - [16/Oct/1997:07:40:50 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562-pm3-138.lex.infi.net - - [16/Oct/1997:07:40:51 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-pm3-138.lex.infi.net - - [16/Oct/1997:07:40:52 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-pm3-138.lex.infi.net - - [16/Oct/1997:07:41:44 -0700] "GET /amnesty/asa/china/torgeson.html HTTP/1.0" 200 1862-pm3-138.lex.infi.net - - [16/Oct/1997:07:41:47 -0700] "GET /amnesty/asa/china/images/marble3.jpg HTTP/1.0" 200 2518-pm3-138.lex.infi.net - - [16/Oct/1997:07:42:02 -0700] "GET /amnesty/asa/china/images/wall.jpg HTTP/1.0" 200 16469-pm3-138.lex.infi.net - - [16/Oct/1997:07:42:19 -0700] "GET /amnesty/asa/china/images/kris.jpg HTTP/1.0" 200 37521-pm3-138.lex.infi.net - - [16/Oct/1997:07:42:32 -0700] "GET /amnesty/asa/china/images/read.gif HTTP/1.0" 200 13330-spo27.homeshopping.com.br - - [16/Oct/1997:07:42:58 -0700] "GET / HTTP/1.0" 200 3082-spo27.homeshopping.com.br - - [16/Oct/1997:07:43:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-pm3-138.lex.infi.net - - [16/Oct/1997:07:43:04 -0700] "GET /amnesty/asa/china/louisa-links.html HTTP/1.0" 200 1076-spo27.homeshopping.com.br - - [16/Oct/1997:07:43:06 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-spo27.homeshopping.com.br - - [16/Oct/1997:07:43:11 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-128.146.150.29 - - [16/Oct/1997:07:43:13 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-128.146.150.29 - - [16/Oct/1997:07:43:15 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-204.183.72.198 - - [16/Oct/1997:07:45:28 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887-204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-204.183.72.198 - - [16/Oct/1997:07:45:30 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-204.183.72.198 - - [16/Oct/1997:07:45:30 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-204.183.72.198 - - [16/Oct/1997:07:45:31 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-204.183.72.198 - - [16/Oct/1997:07:45:31 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-204.183.72.198 - - [16/Oct/1997:07:45:32 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308-204.183.72.198 - - [16/Oct/1997:07:46:44 -0700] "GET /urgact/ HTTP/1.0" 200 8283-207.38.218.82 - - [16/Oct/1997:07:46:50 -0700] "GET /amnesty HTTP/1.0" 301 184-207.38.218.82 - - [16/Oct/1997:07:46:51 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-207.38.218.82 - - [16/Oct/1997:07:46:53 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-207.38.218.82 - - [16/Oct/1997:07:46:54 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:18 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224-171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:22 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76-171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:23 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013-171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:31 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534-207.38.218.82 - - [16/Oct/1997:07:48:08 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-207.38.218.82 - - [16/Oct/1997:07:48:11 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-207.38.218.82 - - [16/Oct/1997:07:48:13 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-207.38.218.82 - - [16/Oct/1997:07:48:15 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-207.38.218.82 - - [16/Oct/1997:07:48:19 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367-207.38.218.82 - - [16/Oct/1997:07:48:19 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543-207.38.218.82 - - [16/Oct/1997:07:48:20 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233-207.38.218.82 - - [16/Oct/1997:07:48:21 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841-207.38.218.82 - - [16/Oct/1997:07:48:21 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291-207.38.218.82 - - [16/Oct/1997:07:48:22 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021-207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380-207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362-207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889-207.38.218.82 - - [16/Oct/1997:07:48:26 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673-207.38.218.82 - - [16/Oct/1997:07:48:26 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447-207.38.218.82 - - [16/Oct/1997:07:48:27 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482-207.38.218.82 - - [16/Oct/1997:07:48:27 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849-207.38.218.82 - - [16/Oct/1997:07:48:28 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493-207.38.218.82 - - [16/Oct/1997:07:48:29 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612-207.38.218.82 - - [16/Oct/1997:07:48:34 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731-207.38.218.82 - - [16/Oct/1997:07:48:37 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924-207.38.218.82 - - [16/Oct/1997:07:48:37 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914-207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190-207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938-207.38.218.82 - - [16/Oct/1997:07:48:39 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865-207.38.218.82 - - [16/Oct/1997:07:48:40 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882-207.38.218.82 - - [16/Oct/1997:07:48:41 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-207.38.218.82 - - [16/Oct/1997:07:48:41 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311-207.38.218.82 - - [16/Oct/1997:07:48:42 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951-207.38.218.82 - - [16/Oct/1997:07:48:43 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191-207.38.218.82 - - [16/Oct/1997:07:48:43 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155-207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157-207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946-207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170-207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786-207.38.218.82 - - [16/Oct/1997:07:48:45 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591-207.38.218.82 - - [16/Oct/1997:07:48:48 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 16384-207.38.218.82 - - [16/Oct/1997:07:48:54 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 304 --207.38.218.82 - - [16/Oct/1997:07:48:54 -0700] "GET /amnesty/welcome.html HTTP/1.0" 304 --207.38.218.82 - - [16/Oct/1997:07:48:55 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 304 --207.38.218.82 - - [16/Oct/1997:07:48:56 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 206 318-207.38.218.82 - - [16/Oct/1997:07:49:03 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 206 14999-207.38.218.82 - - [16/Oct/1997:07:50:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-207.38.218.82 - - [16/Oct/1997:07:50:29 -0700] "GET /amnesty/joinai.html HTTP/1.0" 304 --207.38.218.82 - - [16/Oct/1997:07:50:30 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-208.133.54.8 - - [16/Oct/1997:07:51:45 -0700] "GET / HTTP/1.0" 200 3082-208.133.54.8 - - [16/Oct/1997:07:51:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-208.133.54.8 - - [16/Oct/1997:07:51:49 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-208.133.54.8 - - [16/Oct/1997:07:51:50 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-208.133.54.8 - - [16/Oct/1997:07:52:02 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-208.133.54.8 - - [16/Oct/1997:07:52:02 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-208.133.54.8 - - [16/Oct/1997:07:52:03 -0700] "GET /ainews.html HTTP/1.0" 200 13435-208.133.54.8 - - [16/Oct/1997:07:52:04 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-208.133.54.8 - - [16/Oct/1997:07:52:04 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-208.133.54.8 - - [16/Oct/1997:07:52:05 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-208.133.54.8 - - [16/Oct/1997:07:52:05 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-208.133.54.8 - - [16/Oct/1997:07:52:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-208.133.54.8 - - [16/Oct/1997:07:52:07 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-208.133.54.8 - - [16/Oct/1997:07:52:08 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-208.133.54.8 - - [16/Oct/1997:07:52:57 -0700] "GET /peru/aatiger.html HTTP/1.0" 200 10330-208.133.54.8 - - [16/Oct/1997:07:52:58 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-208.133.54.8 - - [16/Oct/1997:07:53:15 -0700] "GET /peru/peru.html HTTP/1.0" 200 12264-207.8.177.135 - - [16/Oct/1997:07:55:41 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-207.8.177.135 - - [16/Oct/1997:07:55:55 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-207.8.177.135 - - [16/Oct/1997:07:56:02 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-207.8.177.135 - - [16/Oct/1997:07:56:14 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-207.8.177.135 - - [16/Oct/1997:07:56:17 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-207.8.177.135 - - [16/Oct/1997:07:56:23 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-207.8.177.135 - - [16/Oct/1997:07:56:23 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-207.8.177.135 - - [16/Oct/1997:07:56:25 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-207.8.177.135 - - [16/Oct/1997:07:56:26 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-207.8.177.135 - - [16/Oct/1997:07:56:26 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-207.8.177.135 - - [16/Oct/1997:07:56:29 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-207.8.177.135 - - [16/Oct/1997:07:56:29 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-207.8.177.135 - - [16/Oct/1997:07:56:30 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-207.8.177.135 - - [16/Oct/1997:07:56:34 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-207.8.177.135 - - [16/Oct/1997:07:56:38 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-207.8.177.135 - - [16/Oct/1997:07:56:41 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-207.8.177.135 - - [16/Oct/1997:07:56:41 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-207.8.177.135 - - [16/Oct/1997:07:56:47 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-pm3-138.lex.infi.net - - [16/Oct/1997:07:56:52 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-207.8.177.135 - - [16/Oct/1997:07:56:52 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-207.8.177.135 - - [16/Oct/1997:07:56:54 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-207.8.177.135 - - [16/Oct/1997:07:56:54 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-207.8.177.135 - - [16/Oct/1997:07:57:00 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-207.8.177.135 - - [16/Oct/1997:07:57:00 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-pm3-138.lex.infi.net - - [16/Oct/1997:07:57:18 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731-pm3-138.lex.infi.net - - [16/Oct/1997:07:57:20 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914-pm3-138.lex.infi.net - - [16/Oct/1997:07:57:21 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924-207.8.177.135 - - [16/Oct/1997:07:57:27 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-207.8.177.135 - - [16/Oct/1997:07:57:27 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-207.8.177.135 - - [16/Oct/1997:07:57:28 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-207.8.177.135 - - [16/Oct/1997:07:57:58 -0700] "GET /amnesty/joinai.txt HTTP/1.0" 200 1914-207.8.177.135 - - [16/Oct/1997:07:58:23 -0700] "GET /amnesty/vgroups.html HTTP/1.0" 200 4391-207.8.177.135 - - [16/Oct/1997:07:58:25 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-207.8.177.135 - - [16/Oct/1997:07:58:26 -0700] "GET /amnesty/images/groucont.gif HTTP/1.0" 200 669-207.8.177.135 - - [16/Oct/1997:07:58:26 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-207.8.177.135 - - [16/Oct/1997:07:58:29 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-207.8.177.135 - - [16/Oct/1997:07:58:42 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575-207.8.177.135 - - [16/Oct/1997:07:58:44 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161-207.8.177.135 - - [16/Oct/1997:07:58:46 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013-207.8.177.135 - - [16/Oct/1997:07:58:47 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257-207.8.177.135 - - [16/Oct/1997:07:58:47 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471-207.8.177.135 - - [16/Oct/1997:07:58:49 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-207.8.177.135 - - [16/Oct/1997:07:58:53 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-207.8.177.135 - - [16/Oct/1997:07:58:53 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399-207.8.177.135 - - [16/Oct/1997:07:58:59 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430-207.8.177.135 - - [16/Oct/1997:07:59:01 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-207.8.177.135 - - [16/Oct/1997:07:59:07 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-207.8.177.135 - - [16/Oct/1997:07:59:08 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-207.8.177.135 - - [16/Oct/1997:07:59:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-204.232.49.30 - - [16/Oct/1997:07:59:37 -0700] "GET / HTTP/1.0" 200 3082-204.232.49.30 - - [16/Oct/1997:07:59:38 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-204.232.49.30 - - [16/Oct/1997:07:59:38 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-204.232.49.30 - - [16/Oct/1997:07:59:49 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562-204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493-204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-204.232.49.30 - - [16/Oct/1997:07:59:51 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-158.5.27.50 - - [16/Oct/1997:07:59:52 -0700] "GET /amnesty/mideast/iraqar.html HTTP/1.0" 200 15153-204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-204.232.49.30 - - [16/Oct/1997:08:00:16 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841-204.232.49.30 - - [16/Oct/1997:08:00:16 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-204.232.49.30 - - [16/Oct/1997:08:00:17 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367-204.232.49.30 - - [16/Oct/1997:08:00:18 -0700] "GET /home.html HTTP/1.0" 200 17233-204.232.49.30 - - [16/Oct/1997:08:00:18 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612-204.232.49.30 - - [16/Oct/1997:08:00:20 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362-204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482-204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889-204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447-204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021-204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849-204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670-204.232.49.30 - - [16/Oct/1997:08:00:25 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-204.232.49.30 - - [16/Oct/1997:08:00:28 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166-204.232.49.30 - - [16/Oct/1997:08:00:28 -0700] "GET /write.html HTTP/1.0" 200 9408-204.232.49.30 - - [16/Oct/1997:08:00:52 -0700] "GET / HTTP/1.0" 200 --204.232.49.30 - - [16/Oct/1997:08:00:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-204.232.49.30 - - [16/Oct/1997:08:00:53 -0700] "GET /images/spot5.gif HTTP/1.0" 304 --208.226.16.80 - - [16/Oct/1997:08:00:57 -0700] "GET / HTTP/1.0" 200 3082-204.232.49.30 - - [16/Oct/1997:08:00:58 -0700] "GET /write.html HTTP/1.0" 200 9408-204.232.49.30 - - [16/Oct/1997:08:00:59 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166-204.232.49.30 - - [16/Oct/1997:08:01:00 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --208.226.16.80 - - [16/Oct/1997:08:01:39 -0700] "GET / HTTP/1.0" 200 3082-204.232.49.30 - - [16/Oct/1997:08:02:11 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308-204.232.49.30 - - [16/Oct/1997:08:02:11 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-204.232.49.30 - - [16/Oct/1997:08:02:12 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887-208.226.16.80 - - [16/Oct/1997:08:02:40 -0700] "GET / HTTP/1.0" 200 3082-208.226.16.80 - - [16/Oct/1997:08:02:45 -0700] "GET / HTTP/1.0" 200 3082-pm3-138.lex.infi.net - - [16/Oct/1997:08:04:03 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 9230-204.232.49.30 - - [16/Oct/1997:08:04:17 -0700] "GET /joinai.html HTTP/1.0" 200 4054-204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --204.232.49.30 - - [16/Oct/1997:08:04:19 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.232.49.30 - - [16/Oct/1997:08:04:20 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-ad20-094.compuserve.com - - [16/Oct/1997:08:04:39 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527-ad20-094.compuserve.com - - [16/Oct/1997:08:04:43 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368-ad20-094.compuserve.com - - [16/Oct/1997:08:04:55 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380-ad20-094.compuserve.com - - [16/Oct/1997:08:04:59 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363-ad20-094.compuserve.com - - [16/Oct/1997:08:04:59 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399-ad20-094.compuserve.com - - [16/Oct/1997:08:05:02 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329-ad20-094.compuserve.com - - [16/Oct/1997:08:05:04 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352-ad20-094.compuserve.com - - [16/Oct/1997:08:05:06 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317-ad20-094.compuserve.com - - [16/Oct/1997:08:05:06 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384-ad20-094.compuserve.com - - [16/Oct/1997:08:05:09 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383-ad20-094.compuserve.com - - [16/Oct/1997:08:05:11 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352-204.232.49.30 - - [16/Oct/1997:08:05:12 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-ad20-094.compuserve.com - - [16/Oct/1997:08:05:12 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403-ad20-094.compuserve.com - - [16/Oct/1997:08:05:13 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366-204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-ad20-094.compuserve.com - - [16/Oct/1997:08:05:14 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432-204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-ad20-094.compuserve.com - - [16/Oct/1997:08:05:16 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344-204.232.49.30 - - [16/Oct/1997:08:05:17 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-204.232.49.30 - - [16/Oct/1997:08:05:17 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-ad20-094.compuserve.com - - [16/Oct/1997:08:05:18 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359-204.232.49.30 - - [16/Oct/1997:08:05:18 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-ad20-094.compuserve.com - - [16/Oct/1997:08:05:19 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592-ad20-094.compuserve.com - - [16/Oct/1997:08:05:19 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352-204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-204.232.49.30 - - [16/Oct/1997:08:05:20 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-204.232.49.30 - - [16/Oct/1997:08:05:25 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-ad20-094.compuserve.com - - [16/Oct/1997:08:05:35 -0700] "GET /amnesty/mideast/saudi.html HTTP/1.0" 200 8072-ad20-094.compuserve.com - - [16/Oct/1997:08:05:35 -0700] "GET /amnesty/mideast/sauflag.gif HTTP/1.0" 200 3101-204.232.49.30 - - [16/Oct/1997:08:05:46 -0700] "GET /about.html HTTP/1.0" 200 6902-ad20-094.compuserve.com - - [16/Oct/1997:08:05:46 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202-204.232.49.30 - - [16/Oct/1997:08:05:47 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/where.gif HTTP/1.0" 200 605-ad20-094.compuserve.com - - [16/Oct/1997:08:05:52 -0700] "GET /amnesty/mideast/saudi.jpg HTTP/1.0" 200 8769-204.232.49.30 - - [16/Oct/1997:08:06:10 -0700] "GET /ainews.html HTTP/1.0" 200 13435-204.232.49.30 - - [16/Oct/1997:08:06:10 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-204.232.49.30 - - [16/Oct/1997:08:06:12 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-204.232.49.30 - - [16/Oct/1997:08:06:12 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-204.232.49.30 - - [16/Oct/1997:08:06:13 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-204.232.49.30 - - [16/Oct/1997:08:06:13 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-208.226.16.80 - - [16/Oct/1997:08:06:20 -0700] "GET / HTTP/1.0" 200 3082-204.232.49.30 - - [16/Oct/1997:08:06:29 -0700] "GET /ainews/china/execrec.html HTTP/1.0" 200 6897-204.232.49.30 - - [16/Oct/1997:08:06:30 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:22 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:23 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:39 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ad20-094.compuserve.com - - [16/Oct/1997:08:08:20 -0700] "GET /amnesty/mideast/moroc.html HTTP/1.0" 200 6539-ad20-094.compuserve.com - - [16/Oct/1997:08:08:24 -0700] "GET /amnesty/mideast/morflag.gif HTTP/1.0" 200 1680-ad20-094.compuserve.com - - [16/Oct/1997:08:09:09 -0700] "GET /amnesty/mideast/morws.jpg HTTP/1.0" 200 17585-ppp4-35.igc.org - - [16/Oct/1997:08:11:14 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:14 -0700] "GET /images/hometake.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:15 -0700] "GET /home.html HTTP/1.0" 200 17233-ppp4-35.igc.org - - [16/Oct/1997:08:11:15 -0700] "GET /images/writbut.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:16 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:16 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:17 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:17 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:19 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/homenew.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/homeside.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:21 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562-ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:24 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:24 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:26 -0700] "GET /regions/index.html HTTP/1.0" 200 2312-ppp4-35.igc.org - - [16/Oct/1997:08:11:27 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:33 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304-ppp4-35.igc.org - - [16/Oct/1997:08:11:34 -0700] "GET /images/picasso.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:11:34 -0700] "GET /images/women05.jpg HTTP/1.0" 304 --ad20-094.compuserve.com - - [16/Oct/1997:08:11:38 -0700] "GET /amnesty/mideast/index.html HTTP/1.0" 200 3104-ad20-094.compuserve.com - - [16/Oct/1997:08:11:47 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682-ad20-094.compuserve.com - - [16/Oct/1997:08:12:09 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:39 -0700] "GET /amnesty HTTP/1.0" 301 184-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:40 -0700] "GET /amnesty/ HTTP/1.0" 200 3082-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:43 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:45 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:13 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:18 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:19 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:20 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:24 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:24 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:25 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:25 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:30 -0700] "GET /amnesty/abolish/index.html HTTP/1.0" 200 6318-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:33 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:34 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:35 -0700] "GET /amnesty/abolish/images/clock6.gif HTTP/1.0" 200 11949-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/abolish/images/clock4.gif HTTP/1.0" 200 37947-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:39 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:41 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-p03-54.onyx.net - - [16/Oct/1997:08:13:44 -0700] "GET /amnesty/ai_gloss.html HTTP/1.0" 200 6214-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:46 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-p03-54.onyx.net - - [16/Oct/1997:08:13:47 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:58 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:05 -0700] "GET /amnesty/abolish/dpfacts.html HTTP/1.0" 200 14087-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:06 -0700] "GET /amnesty/abolish/images/greysand.gif HTTP/1.0" 200 10546-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:09 -0700] "GET /amnesty/images/blkcnd2x.gif HTTP/1.0" 200 1439-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:11 -0700] "GET /amnesty/abolish/images/airedsnd.gif HTTP/1.0" 200 8856-p03-54.onyx.net - - [16/Oct/1997:08:14:12 -0700] "GET /amnesty/regions.html HTTP/1.0" 200 4886-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:15 -0700] "GET /amnesty/images/deathbux.gif HTTP/1.0" 200 1667-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:27 -0700] "GET /amnesty/abolish/8'5uaup.html HTTP/1.0" 200 4586-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:30 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:30 -0700] "GET /amnesty/tools/ffffff.gif HTTP/1.0" 200 35-p03-54.onyx.net - - [16/Oct/1997:08:14:42 -0700] "GET /amnesty/index.html HTTP/1.0" 200 3082-p03-54.onyx.net - - [16/Oct/1997:08:14:45 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-p03-54.onyx.net - - [16/Oct/1997:08:14:48 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:54 -0700] "GET /amnesty/abolish/executio.html HTTP/1.0" 200 5523-p03-54.onyx.net - - [16/Oct/1997:08:14:56 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-p03-54.onyx.net - - [16/Oct/1997:08:15:24 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054-ww-tr03.proxy.aol.com - - [16/Oct/1997:08:15:47 -0700] "GET /amnesty/abolish/leavrick.html HTTP/1.0" 200 1585-hera-18.hermesnet.net - - [16/Oct/1997:08:18:45 -0700] "GET / HTTP/1.0" 200 3082-hera-18.hermesnet.net - - [16/Oct/1997:08:18:49 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-hera-18.hermesnet.net - - [16/Oct/1997:08:18:52 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:23 -0700] "GET /amnesty/index.html HTTP/1.0" 200 3082-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:32 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:33 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 304 --ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:42 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:44 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:56 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089-nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:20:57 -0700] "GET /comm/herbert.html HTTP/1.0" 200 1563-ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:59 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:00 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:02 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:03 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:03 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:05 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:05 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:06 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:07 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:08 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277-user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:28 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:31 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:31 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:32 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:34 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:50 -0700] "GET /amnesty/legal.html HTTP/1.0" 200 5654-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:53 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:54 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:55 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409-ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:56 -0700] "GET /amnesty/images/clear1.jpg HTTP/1.0" 200 849-152.157.224.6 - - [16/Oct/1997:08:22:12 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:24 -0700] "GET /amnesty/casework/index.html HTTP/1.0" 200 2974-152.157.224.6 - - [16/Oct/1997:08:22:24 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:26 -0700] "GET /amnesty/images/aiusarex.gif HTTP/1.0" 200 3237-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:27 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/casework/images/bothlogo.gif HTTP/1.0" 200 8650-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714-152.157.224.6 - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027-152.157.224.6 - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367-152.157.224.6 - - [16/Oct/1997:08:22:30 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766-ppp4-35.igc.org - - [16/Oct/1997:08:22:46 -0700] "GET /regions/maregcon.html HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:22:47 -0700] "GET /images/picasso.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:22:47 -0700] "GET /images/women05.jpg HTTP/1.0" 304 --ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:48 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575-ppp4-35.igc.org - - [16/Oct/1997:08:22:50 -0700] "GET /regions/maregcon.html HTTP/1.0" 304 --ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471-ppp4-35.igc.org - - [16/Oct/1997:08:22:52 -0700] "GET /images/picasso.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:22:52 -0700] "GET /images/women05.jpg HTTP/1.0" 304 --ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:56 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430-ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:58 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257-ww-to03.proxy.aol.com - - [16/Oct/1997:08:23:08 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399-nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:13 -0700] "GET /comm/herbert.html HTTP/1.0" 304 --nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:14 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43-nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:20 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517-nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:25 -0700] "GET /comm/images/people/herbert4.jpg HTTP/1.0" 200 11129-ppp4-35.igc.org - - [16/Oct/1997:08:27:11 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304-ppp4-35.igc.org - - [16/Oct/1997:08:27:14 -0700] "GET /images/picasso.gif HTTP/1.0" 304 --ppp4-35.igc.org - - [16/Oct/1997:08:27:14 -0700] "GET /images/women05.jpg HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:29:55 -0700] "GET /argact/ HTTP/1.0" 404 160-204.48.151.245 - - [16/Oct/1997:08:30:03 -0700] "GET /urgact/ HTTP/1.0" 200 8283-204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875-204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714-204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-204.48.151.245 - - [16/Oct/1997:08:30:06 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634-204.48.151.245 - - [16/Oct/1997:08:30:06 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782-204.48.151.245 - - [16/Oct/1997:08:30:10 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766-209.76.123.200 - - [16/Oct/1997:08:31:26 -0700] "GET /weeklyua.html HTTP/1.0" 200 11321-204.48.151.245 - - [16/Oct/1997:08:32:32 -0700] "GET /urgact/ HTTP/1.0" 200 --204.48.151.245 - - [16/Oct/1997:08:32:36 -0700] "GET /images/logo2.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:37 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:37 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:38 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:39 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:32:43 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:13 -0700] "GET /home.html HTTP/1.0" 200 3854-204.48.151.245 - - [16/Oct/1997:08:33:26 -0700] "GET /index.html HTTP/1.0" 200 3082-204.48.151.245 - - [16/Oct/1997:08:33:27 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-204.48.151.245 - - [16/Oct/1997:08:33:27 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ppp37.igc.org - - [16/Oct/1997:08:33:28 -0700] "GET /casework/ HTTP/1.0" 200 2974-ppp37.igc.org - - [16/Oct/1997:08:33:29 -0700] "GET /images/aiusarex.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:30 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:30 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:31 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:31 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:33:49 -0700] "GET /joinai.html HTTP/1.0" 200 4054-204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-204.48.151.245 - - [16/Oct/1997:08:34:09 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-204.185.34.45 - - [16/Oct/1997:08:36:37 -0700] "GET /asa/china/ HTTP/1.0" 200 18000-204.185.34.45 - - [16/Oct/1997:08:36:46 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336-204.185.34.45 - - [16/Oct/1997:08:36:49 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951-204.185.34.45 - - [16/Oct/1997:08:37:11 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 8192-204.185.34.45 - - [16/Oct/1997:08:37:21 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049-204.185.34.45 - - [16/Oct/1997:08:37:37 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241-204.185.34.45 - - [16/Oct/1997:08:37:38 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212-204.185.34.45 - - [16/Oct/1997:08:37:39 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247-204.185.34.45 - - [16/Oct/1997:08:37:47 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196-204.185.34.45 - - [16/Oct/1997:08:37:48 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236-204.185.34.45 - - [16/Oct/1997:08:37:53 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411-204.185.34.45 - - [16/Oct/1997:08:38:00 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202-204.185.34.45 - - [16/Oct/1997:08:38:16 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648-204.185.34.45 - - [16/Oct/1997:08:38:17 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 8192-204.185.34.45 - - [16/Oct/1997:08:38:17 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 16384-ppp31.igc.org - - [16/Oct/1997:08:38:50 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:51 -0700] "GET /images/hometake.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:51 -0700] "GET /images/writbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:52 -0700] "GET /home.html HTTP/1.0" 200 17234-ppp31.igc.org - - [16/Oct/1997:08:38:52 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:53 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:53 -0700] "GET /images/spanbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/homenew.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/homeside.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:56 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:58 -0700] "GET /images/savebutx.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/countbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/getbut.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/membutx.gif HTTP/1.0" 304 --ppp31.igc.org - - [16/Oct/1997:08:39:50 -0700] "GET /members/afreport.html HTTP/1.0" 401 350-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:05 -0700] "GET / HTTP/1.0" 200 3082-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:06 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:11 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ppp31.igc.org - amnesty [16/Oct/1997:08:40:11 -0700] "GET /members/afreport.html HTTP/1.0" 200 450-204.48.151.245 - - [16/Oct/1997:08:40:44 -0700] "GET /urgact/ HTTP/1.0" 200 --shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:46 -0700] "GET /images/dot.gif HTTP/1.0" 200 946-204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/logo2.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 --shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:46 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:47 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769-204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:51 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:51 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:52 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:52 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:53 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:55 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:59 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:00 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:02 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:05 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:05 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:09 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-204.48.151.245 - - [16/Oct/1997:08:41:21 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:41:21 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:41:22 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 --shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:37 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:37 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:39 -0700] "GET /ainews.html HTTP/1.0" 200 13435-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:39 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:41 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:44 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448-204.48.151.245 - - [16/Oct/1997:08:41:45 -0700] "GET /urgact/contact.html HTTP/1.0" 200 882-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:52 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:52 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:53 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:53 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:58 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673-204.48.151.245 - - [16/Oct/1997:08:42:04 -0700] "GET /index.html HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:06 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-204.48.151.245 - - [16/Oct/1997:08:42:15 -0700] "GET /joinai.html HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:18 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:18 -0700] "GET /images/homebut.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:20 -0700] "GET /images/cabut.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:23 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 --204.48.151.245 - - [16/Oct/1997:08:42:24 -0700] "GET /images/newbut.gif HTTP/1.0" 304 --shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:37 -0700] "GET /candatop.html HTTP/1.0" 200 10629-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:38 -0700] "GET /images/done.gif HTTP/1.0" 200 4785-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:40 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:41 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:42 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:43 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:44 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:44 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:45 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:46 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:46 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:48 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:51 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:33 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:33 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:37 -0700] "GET /weeklyua.html HTTP/1.0" 200 11321-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:00 -0700] "GET /about.html HTTP/1.0" 200 6902-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:01 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:01 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:03 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:07 -0700] "GET /images/where.gif HTTP/1.0" 200 605-ppp48.centraltx.net - - [16/Oct/1997:08:49:35 -0700] "GET / HTTP/1.0" 200 3082-ppp48.centraltx.net - - [16/Oct/1997:08:49:38 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170-ppp48.centraltx.net - - [16/Oct/1997:08:49:47 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372-ppp48.centraltx.net - - [16/Oct/1997:08:49:53 -0700] "GET /joinai.html HTTP/1.0" 200 4054-ppp48.centraltx.net - - [16/Oct/1997:08:49:55 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /about/history.html HTTP/1.0" 200 10342-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082-ppp48.centraltx.net - - [16/Oct/1997:08:49:58 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596-ppp48.centraltx.net - - [16/Oct/1997:08:49:59 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277-ppp48.centraltx.net - - [16/Oct/1997:08:49:59 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027-ppp48.centraltx.net - - [16/Oct/1997:08:50:00 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425-ppp48.centraltx.net - - [16/Oct/1997:08:50:00 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:01 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:04 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400-shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:07 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250-ppp48.centraltx.net - - [16/Oct/1997:08:50:09 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855-ppp48.centraltx.net - - [16/Oct/1997:08:50:15 -0700] "GET /about.html HTTP/1.0" 200 6902-ppp48.centraltx.net - - [16/Oct/1997:08:50:19 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509-ppp48.centraltx.net - - [16/Oct/1997:08:50:20 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505-ppp48.centraltx.net - - [16/Oct/1997:08:50:22 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191-ppp48.centraltx.net - - [16/Oct/1997:08:50:24 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526-ppp48.centraltx.net - - [16/Oct/1997:08:50:25 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380-ppp48.centraltx.net - - [16/Oct/1997:08:50:27 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293-ecarh29c.nortel.ca - - [16/Oct/1997:08:50:34 -0700] "GET /country/balkans HTTP/1.0" 301 196-ecarh29c.nortel.ca - - [16/Oct/1997:08:50:35 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778-ecarh29c.nortel.ca - - [16/Oct/1997:08:50:38 -0700] "GET /country/balkans/images/dot.gif HTTP/1.0" 200 46-ecarh29c.nortel.ca - - [16/Oct/1997:08:50:38 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908-ppp48.centraltx.net - - [16/Oct/1997:08:50:40 -0700] "GET /quiz.html HTTP/1.0" 200 10126-ecarh29c.nortel.ca - - [16/Oct/1997:08:50:41 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638-ppp48.centraltx.net - - [16/Oct/1997:08:50:42 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43
file too large to diff
@@ -1,1 +0,0 @@-25 23 300 -400 899 9876 -98744 97687676543 -98765432187
binary file changed (32 → absent bytes)
@@ -1,1 +0,0 @@-ª»ÌÝccdd
@@ -1,11 +0,0 @@-221 2360199 936 3615299 96977709 71-221 2360399 855 5445599 96978527 126-221 2390199 974 4298199 96980122 990-221 2390399 855 5404599 96976885 35-222 2332099 426 6814599 96977173 4850-222 2332099 -15 9999999 96978457 533-222 2340599 855 8442799 96980047 8-222 2341299 855 7081599 96979104 11-223 2340099 855 2484499 96977739 564-223 2340199 -15 9999999 96979345 143-
binary file changed (240 → absent bytes)
@@ -1,40 +0,0 @@-#include <stdio.h>--/* Reads ascii call detail records from stdin.- * Writes scampRec binary call detail records on stdout.- */--typedef struct-{- unsigned char uc;- signed char sc;- unsigned short us;- signed short ss;- signed short ss2;- unsigned int ui;- signed int si;- unsigned long long ull;- signed long long sll;-} binRec_t;----int readAscii(FILE *in, binRec_t *r){- int success = fscanf(in, "%hhu %hhd %hu %hd %hd %u %d %llu %lld\n",- &(r->uc), &(r->sc), - &(r->us), &(r->ss), &(r->ss2),- &(r->ui), &(r->si),- &(r->ull),&(r->sll)); - return success;-}--void writeBinary(FILE *out, binRec_t *r){- fwrite(r, sizeof(binRec_t), 1, out);-}--int main(){- binRec_t current;- while (readAscii(stdin, ¤t) != EOF)- writeBinary(stdout, ¤t);- return 0;-}
@@ -1,3 +0,0 @@-8,Hermione-3,Ron-5,Harry
@@ -1,155 +0,0 @@-{-# LANGUAGE FlexibleContexts, TypeFamilies, TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.BaseTypes- Description : Base types provided by Pads- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- Some useful Pads types (parsers) implemented by the code generator in lieu of- writing them by hand.---}--module Language.Pads.BaseTypes where--import Language.Pads.Source-import Language.Pads.Errors -import Language.Pads.Generic-import Language.Pads.MetaData-import Language.Pads.CoreBaseTypes-import Language.Pads.Quote-import Language.Pads.RegExp-import Language.Pads.PadsPrinter-import Data.Time-import System.Locale as Locale-import Text.PrettyPrint.Mainland (text)-import Text.PrettyPrint.Mainland.Class--import qualified Data.Char as C-import qualified Data.List as L-import Data.Data-import qualified Data.ByteString as B --[pads|--- string that stops in a newline-type StringEOR = [Char] terminator EOR-type Line a = (a, EOR)-type StringLn = [Char] terminator (Try EOR)-type StringLnP (p :: String -> Bool) = constrain s :: StringLn where <| p s |> -type StringESCLn (p :: (Char, [Char])) = StringPESC <|(True, p)|> -type StringESC (p :: (Char, [Char])) = StringPESC <|(False, p)|> --data PMaybe a = PJust a- | PNothing Void-obtain Maybe a from PMaybe a using <|(pm2m,m2pm)|>--|]---- | Pads maybe to Haskell maybe-pm2m :: Span -> (PMaybe a, PMaybe_md a_md) -> (Maybe a, Maybe_md a_md)-pm2m p (PJust x, md) = (Just x, md)-pm2m p (PNothing,md) = (Nothing,md)---- | Haskell maybe to Pads maybe-m2pm :: (Maybe a, Maybe_md a_md) -> (PMaybe a, PMaybe_md a_md)-m2pm (Just x, md) = (PJust x, md)-m2pm (Nothing,md) = (PNothing,md)---[pads|-type Lit (x::String) = (Void, x)-type LitRE (x::RE) = (Void, x)-|]--[pads| obtain Bool from Bytes 1 using <|(bTobl,blTob)|> |]--- | Bytes to Bool-bTobl :: Span -> (Bytes,Bytes_md) -> (Bool,Bool_md)-bTobl p (bytes,md) = (fromIntegral (bytes `B.index` 0)==(1::Int), md)--- | Bool to Bytes-blTob :: (Bool,Bool_md) -> (Bytes,Bytes_md)-blTob (b,md) = (B.singleton (if b then 1 else 0), md)---[pads| type DateFSE (fmt :: String, se :: RE) = obtain UTCTime from StringSE se using <| (strToUTC fmt, utcToStr fmt) |> - type DateFC (fmt::String, c::Char) = DateFSE <|(fmt, RE ("[" ++ [c] ++ "]")) |> |] ---- | Coordinated universal time Pads metadata type-type UTCTime_md = Base_md-instance Pretty UTCTime where- ppr utc = text (show utc)---- | UTC parser from a string based on Haskell builtin UTC parser.-strToUTC :: String -> Span -> (StringSE, Base_md) -> (UTCTime, Base_md)-strToUTC fmt pos (input, input_bmd) = - case parseTimeM True Data.Time.defaultTimeLocale fmt input of - Nothing -> (gdef, mergeBaseMDs [errPD, input_bmd])- Just t -> (t, input_bmd)- where- errPD = mkErrBasePD (TransformToDstFail "DateFSE" input " (conversion failed)") (Just pos)---- | Default time of: 0h Nov 17, 1858-uTCTime_def = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 0)---- | Format a UTC instance as a string.-utcToStr :: String -> (UTCTime, Base_md) -> (StringSE, Base_md) -utcToStr fmt (utcTime, bmd) = (formatTime Data.Time.defaultTimeLocale fmt utcTime, bmd)---[pads| type TimeZoneSE (se :: RE) = obtain TimeZone from StringSE se using <| (strToTz, tzToStr) |> - type TimeZoneC (c::Char) = TimeZoneSE <|RE ("[" ++ [c] ++ "]") |> |] --type TimeZone_md = Base_md-instance Pretty TimeZone where- ppr tz = text (show tz)---- | Timezone parser-strToTz :: Span -> (StringSE, Base_md) -> (TimeZone, Base_md)-strToTz pos (input, input_bmd) = - case parseTimeM True Data.Time.defaultTimeLocale "%z" input of - Nothing -> (gdef, mergeBaseMDs [mkErrBasePD (TransformToDstFail "TimeZoneSE" input " (conversion failed)") (Just pos), input_bmd])- Just t -> (t, input_bmd)---- | Timezone formatter-tzToStr :: (TimeZone, Base_md) -> (StringSE, Base_md) -tzToStr (tz, bmd) = (h ++ ":" ++ m, bmd)- where (h,m) = splitAt 3 (show tz)--timeZone_def = utc--[pads| type Phex32FW (size :: Int) = obtain Int from StringFW size using <| (hexStr2Int,int2HexStr size) |> |] ---- | Transform a hexadecimal string to an int-hexStr2Int :: Span -> (StringFW, Base_md) -> (Int, Base_md)-hexStr2Int src_pos (s,md) = if good then (intList2Int ints 0, md)- else (0, mkErrBasePD (TransformToDstFail "StrHex" s " (non-hex digit)") (Just src_pos))- where- hc2int c = if C.isHexDigit c then (C.digitToInt c,True) else (0,False)- (ints,bools) = unzip (map hc2int s)- good = (L.and bools) && (length ints > 0)- intList2Int digits a = case digits of- [] -> a- (d:ds) -> intList2Int ds ((16 * a) + d)---- | Transform an int into a hexadecimal string-int2HexStr :: Int -> (Int, Base_md) -> (StringFW, Base_md)-int2HexStr size (x,md)- | length result == size && wasPos = (result, md) - | not wasPos = (Prelude.take size result, - mkErrBasePD (TransformToSrcFail "StrHex" (show x) (" (Expected positive number)")) Nothing)- | otherwise = (Prelude.take size result,- mkErrBasePD (TransformToSrcFail "StrHex" (show x) (" (too big to fit in "++ (show size) ++" characters)")) Nothing)- where- cvt rest a = if rest < 16 then {- reverse $ -} (C.intToDigit rest) : a- else cvt (rest `div` 16) (C.intToDigit (rest `mod` 16) : a)- (wasPos,x') = if x < 0 then (False, -x) else (True, x)- temp = cvt x' []- padding = size - (length temp)- stutter c n = if n <= 0 then [] else c : (stutter c (n-1))- result = (stutter '0' padding) ++ temp-
@@ -1,1227 +0,0 @@-{-# LANGUAGE TupleSections, ViewPatterns, TemplateHaskell, NamedFieldPuns, ScopedTypeVariables,- RecordWildCards, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.CodeGen- Description : Template Haskell based code generator- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- To the best of my knowledge, all functions defined herein are only ever run at- compile time. These compile time functions are intended to be used in a- quasiquoted context where the runtime system support modules have been properly- imported. See "Examples.First" for the necessary imports.-- The crucial piece of the code generator is 'genParseTy', which translates Pads- syntactic forms into Haskell code for parsing them.---}-module Language.Pads.CodeGen where--import Language.Pads.Syntax as PS-import Language.Pads.MetaData-import Language.Pads.Generic-import Language.Pads.PadsParser-import Language.Pads.CoreBaseTypes-import Language.Pads.TH-import qualified Language.Pads.Errors as E-import qualified Language.Pads.Source as S-import Language.Pads.PadsPrinter--import Language.Haskell.TH -import Language.Haskell.Syntax--import Data.Data-import Data.Char-import qualified Data.Map as M-import qualified Data.List as List-import qualified Data.Maybe as Maybe-import Control.Monad-import Language.Haskell.TH.Syntax (lift)--import qualified Debug.Trace as D---- | -type BString = S.RawStream---- | A function passed into the code generator which gets called on data type--- declarations and returns a list of standalone-deriving declarations.--- Presently this is unused by Pads.-type Derivation = Dec -> Q [Dec]---- | Top level code gen function from Pads decls to Haskell decls-make_pads_declarations :: [PadsDecl] -> Q [Dec]-make_pads_declarations = make_pads_declarations' (const $ return [])---- | Top level code gen function from Pads decls to Haskell expression with just--- the PADS AST (no parser codegen)-make_pads_asts :: [PadsDecl] -> Q Exp-make_pads_asts = let- mpa pd@(PadsDeclType n _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]- mpa pd@(PadsDeclData n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]- mpa pd@(PadsDeclNew n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]- mpa pd@(PadsDeclObtain n _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]- in listE . (map mpa)---- | Top level code gen function from Pads decls to Haskell decls with the--- specified list of type classes for all of the generated Pads types to derive.-make_pads_declarations' :: Derivation -> [PadsDecl] -> Q [Dec]-make_pads_declarations' derivation ds = fmap concat (mapM (genPadsDecl derivation) ds)------------------------------------------------------------------------------------ * Generating Declarations and Code from Individual Pads Declarations--genPadsDecl :: Derivation -> PadsDecl -> Q [Dec]--- ^ Generate all the top level Haskell declarations associated with a single--- Pads declaration.-genPadsDecl derivation pd@(PadsDeclType name args pat padsTy) = do- let typeDecs = mkTyRepMDDecl name args padsTy- parseM <- genPadsParseM name args pat padsTy- parseS <- genPadsParseS name args pat- printFL <- genPadsPrintFL name args pat padsTy- def <- genPadsDef name args pat padsTy- let sigs = mkPadsSignature name args (fmap patType pat)- ast <- astDecl name pd- return $ typeDecs ++ parseM ++ parseS ++ printFL ++ def ++ sigs--genPadsDecl derivation pd@(PadsDeclData name args pat padsData derives) = do- dataDecs <- mkDataRepMDDecl derivation name args padsData derives- parseM <- genPadsDataParseM name args pat padsData - parseS <- genPadsParseS name args pat- printFL <- genPadsDataPrintFL name args pat padsData- def <- genPadsDataDef name args pat padsData- let instances = mkPadsInstance name args (fmap patType pat)- let sigs = mkPadsSignature name args (fmap patType pat)- ast <- astDecl name pd- return $ dataDecs ++ parseM ++ parseS ++ printFL ++ def ++ instances ++ sigs--genPadsDecl derivation pd@(PadsDeclNew name args pat branch derives) = do- dataDecs <- mkNewRepMDDecl derivation name args branch derives- parseM <- genPadsNewParseM name args pat branch - parseS <- genPadsParseS name args pat- printFL <- genPadsNewPrintFL name args pat branch- def <- genPadsNewDef name args pat branch- let instances = mkPadsInstance name args (fmap patType pat)- let sigs = mkPadsSignature name args (fmap patType pat)- ast <- astDecl name pd- return $ dataDecs ++ parseM ++ parseS ++ printFL ++ def ++ instances ++ sigs--genPadsDecl derivation pd@(PadsDeclObtain name args padsTy exp) = do- let mdDec = mkObtainMDDecl name args padsTy- parseM <- genPadsObtainParseM name args padsTy exp- parseS <- genPadsParseS name args Nothing- printFL <- genPadsObtainPrintFL name args padsTy exp- def <- genPadsObtainDef name args padsTy exp- let sigs = mkPadsSignature name args Nothing- ast <- astDecl name pd- return $ mdDec ++ parseM ++ parseS ++ printFL ++ def ++ sigs---- | A Haskell declaration containing the literal Pads AST representation of a--- Pads description (the syntax of Pads encoded as Haskell data constructors)-astDecl name pd = funD (mkName $ "ast_" ++ name) [clause [] (normalB $ lift pd) []]---- | The Haskell 'Type' of a Haskell pattern 'Pat'.-patType :: Pat -> Type-patType p = case p of- LitP lit -> case lit of- CharL c -> VarT ''Char- StringL s -> VarT ''String- TupP ps -> mkTupleT (map patType ps)- SigP p t -> t- ParensP p -> patType p- otherwise -> error $ show p------------------------------------------------------------------------------------ * Generating Rep/MD Type Declarations---- | Make the type declarations for the representation and the metadata of a--- Pads-defined type, @'PadsTy'@.-mkTyRepMDDecl :: UString -> [UString] -> PadsTy -> [Dec]-mkTyRepMDDecl name args ty = [repType, mdType]- where- repType = TySynD (mkRepName name) tyArgs (mkRepTy ty)- mdType = TySynD (mkMDName name) tyArgsMD (mkMDTy False ty)- tyArgs = map (PlainTV . mkName) args- tyArgsMD = map (PlainTV . mkName . (++"_md")) args------------------------------------------------------------------------------------ * Generating Rep/MD Data Declarations---- | Make the data type declarations for the representation and the metadata of--- a Pads-defined data type, @'PadsData'@.-mkDataRepMDDecl :: Derivation -> UString -> [LString] -> PadsData -> [QString] -> Q [Dec]-mkDataRepMDDecl derivation name args branches ds = do- bs' <- mapM (return . mkMDUnion) bs- imdDecl <- dataD (cxt []) (mkIMDName name) tyArgsMD Nothing bs' [derive []]- bs'' <- mapM (return . mkRepUnion) bs- --let ds' = map (conT . mkName . qName) ds- dataDecl <- dataD (cxt []) (mkRepName name) tyArgs Nothing bs'' [derive ds]- derivesData <- derivation dataDecl- derivesImd <- derivation imdDecl- let mdName = mkMDName name- --let bT = bangType (mkStrict NotStrict)- --let mdDeclConstr = normalC mdName $ [bT $ return $ mkTupleT [ConT '' Base_md, imdApp]]- --mdDecl <- newtypeD (cxt []) mdName tyArgsMD Nothing mdDeclConstr []- let mdDecl = TySynD (mkMDName name) tyArgsMD (mkTupleT [ConT ''Base_md, imdApp])- return $ [dataDecl, mdDecl, imdDecl] ++ derivesData ++ derivesImd- where- tyArgs = map (PlainTV . mkName) args- tyArgsMD = map (PlainTV . mkName . (++"_md")) args- imdApp = foldl AppT (ConT (mkIMDName name)) (map (VarT . mkName . (++"_md")) args)- bs = case branches of- PUnion bnchs -> bnchs- PSwitch exp pbs -> [b | (p,b) <- pbs]---- | Convert a Pads strictness annotation into the appropriate Haskell--- strictness annotation in the template haskell Q monad for splicing.-mkStrict :: PadsStrict -> Q Strict-mkStrict NotStrict = bang noSourceUnpackedness noSourceStrictness -- i.e. notStrict-mkStrict IsStrict = bang noSourceUnpackedness sourceStrict -- i.e. isStrict---- | Make the Haskell data type *constructor* (@'normalC'@ and @'recC'@) for the--- given fragment of a Pads type (@'BranchInfo'@).-mkRepUnion :: BranchInfo -> ConQ-mkRepUnion (BConstr c args expM) = normalC (mkConstrName c) reps- where reps = [bangType (mkStrict strict) (return $ mkRepTy ty) | (strict,ty) <- args, hasRep ty]-mkRepUnion (BRecord c fields expM) = recC (mkConstrName c) lreps- where lreps = [ varBangType- (mkName l)- (bangType (mkStrict strict)- (return $ mkRepTy ty))- | (Just l,(strict,ty),_) <- fields, hasRep ty]---- | Make the 'Con' metadata constructor definition for an individual branch of--- a Pads type, which gets used to create the Haskell data type declaration for--- the metadata of a Pads type.-mkMDUnion :: BranchInfo -> Q Con-mkMDUnion (BConstr c args expM) = normalC (mkConstrIMDName c) mds- where - mds = [bangType (mkStrict NotStrict) (return $ mkMDTy False ty) | (_,ty) <- args] --MD , hasRep ty]-mkMDUnion (BRecord c fields expM) = do- { let lmds = [ do { fn <- genLabMDName "m" lM- ; varBangType fn (bangType (mkStrict NotStrict) (return $ mkMDTy False ty))- }- | (lM,(_,ty),_) <- fields- ]- ; recC (mkConstrIMDName c) lmds- }---MD lmds <- return [(mkFieldMDName l,NotStrict,mkMDTy ty) | (Just l,(_,ty),_) <- fields, hasRep ty]---- | Make the type context of a data declaration, consisting of the typeclasses--- instanced by Pads data types.---derive :: [QString] -> CxtQ-derive :: [QString] -> DerivClauseQ-derive ds = derivClause Nothing $ map (conT . mkName . qName) ds- ++ [conT $ mkName d | d<-["Show","Eq","Typeable","Data","Ord"], not (d `elem` map last ds)]------------------------------------------------------------------------------------ * Generating Rep/MD Newtype Declarations---- | Construct the newtype Haskell data declaration from a Pads type defined--- using the "newtype" keyword.-mkNewRepMDDecl :: Derivation -> UString -> [LString] -> BranchInfo -> [QString] -> Q [Dec]-mkNewRepMDDecl derivation name args branch ds = do- imdDecl <- newtypeD (cxt []) (mkIMDName name) tyArgsMD Nothing (mkMDUnion branch) [derive []]- let ds' = map (conT . mkName . qName) ds- dataDecl <- newtypeD (cxt []) (mkRepName name) tyArgs Nothing (mkRepUnion branch) [derive ds]- --[derivClause Nothing ds']- derivesData <- derivation dataDecl- derivesImd <- derivation imdDecl- return $ [dataDecl, mdDecl, imdDecl] ++ derivesData ++ derivesImd- where- mdDecl = TySynD (mkMDName name) tyArgsMD (mkTupleT [ConT ''Base_md, imdApp])- tyArgs = map (PlainTV . mkName) args- tyArgsMD = map (PlainTV . mkName . (++"_md")) args- imdApp = foldl AppT (ConT (mkIMDName name)) (map (VarT . mkName . (++"_md")) args)------------------------------------------------------------------------------------ * Generating MD Type from Obtain Declarations--- Design decision not to do this.---- | Construct the Haskell type synonym declaration for a Pads type declared--- using the "obtain" keyword.-mkObtainMDDecl :: UString -> [UString] -> PadsTy -> [Dec]-mkObtainMDDecl name args ty- = [mdType]- where- mdType = TySynD (mkMDName name) tyArgsMD (mkMDTy False ty)- tyArgsMD = map (PlainTV . mkName . (++"_md")) args------------------------------------------------------------------------------------ * Generating Representation Type of a Type Expression---- | Make the template haskell 'Type' for the given 'PadsTy' pads type, to be--- used anywhere in generated Haskell code where the representation type is--- expected.-mkRepTy :: PadsTy -> Type-mkRepTy ty = case ty of- PPartition pty exp -> mkRepTy pty- PConstrain pat pty exp -> mkRepTy pty - PTransform tySrc tyDest exp -> mkRepTy tyDest - PList ty sep term -> ListT `AppT` mkRepTy ty- PValue exp pty -> mkRepTy pty - PApp tys expM -> foldl1 AppT [mkRepTy ty | ty <- tys, hasRep ty]- PTuple tys -> mkRepTuple tys- PExpression _ -> ConT ''()- PTycon c -> ConT (mkRepQName c)- PTyvar v -> VarT (mkName v) ---- | Make the template haskell 'Type' corresponding to a tuple consisting of the--- given pads types given in list form at compile time '[PadsTy]'.-mkRepTuple :: [PadsTy] -> Type-mkRepTuple tys = case reps of - [] -> ConT ''()- [ty] -> ty- (t:ts) -> mkTupleT reps- where- reps = [mkRepTy ty | ty <- tys, hasRep ty]------------------------------------------------------------------------------------ * Generating Meta-Data Representation of Type Expression---- | Make the template haskell 'Type' corresponding to the externally visible--- metadata of a given 'PadsTy'. The boolean indicates whether or not Pads type--- variables 'PTyvar's should be put in a 'Meta' constructor or merely stuffed--- into a 'VarT' and appended with "_md" postfix. Currently we always do the--- latter (all calls to 'mkMDTy' give False as the boolean).-mkMDTy :: Bool -> PadsTy -> Type-mkMDTy isMeta ty = case ty of- PPartition pty exp -> mkMDTy isMeta pty- PConstrain pat pty exp -> mkMDTy isMeta pty - PTransform src dest exp -> mkMDTy isMeta dest - PList ty sep term -> mkTupleT [ConT ''Base_md, ListT `AppT` mkMDTy isMeta ty]- PValue exp pty -> mkMDTy isMeta pty - PApp tys expM -> foldl1 AppT [mkMDTy isMeta ty | ty <- tys] --MD , hasRep ty]- PTuple tys -> mkMDTuple isMeta tys- PExpression _ -> ConT ''Base_md- PTycon c -> ConT (mkMDQName c)- PTyvar v -> if isMeta- then AppT (ConT ''Meta) (VarT $ mkName v)- else VarT (mkName $ v ++ "_md") ---- | Make the template haskell 'Type' corresponding to a Haskell tuple type--- consisting of the metadata types for the given Pads types '[PadsTy]'.-mkMDTuple :: Bool -> [PadsTy] -> Type-mkMDTuple isMeta tys = case mds of - [] -> ConT ''Base_md- [m] -> mkTupleT [ConT ''Base_md, m] - (m:ms) -> mkTupleT [ConT ''Base_md, mkTupleT mds]- where- mds = [mkMDTy isMeta ty | ty <- tys] --MD , hasRep ty]------------------------------------------------------------------------------------- * Generating Instance Declarations from Data / New Declarations---- | Make the following instance and type instance declarations for a Pads data--- type and new type declaration:------ > [pads| data Foo (Bar1, Bar2, Bar3) = Foo--- > { i1 :: Bar1--- > , i2 :: Bar2 i1--- > , i3 :: Bar3 i2--- > } |]------ > instance Pads1 (Bar1, Bar2, Bar3) Foo Foo_md where--- > parsePP1 = foo_parseM--- > printFL1 = foo_printFL--- > def1 = foo_def--- > type instance Meta Foo = Foo_md--- > type instance PadsArg Foo = (Bar1, Bar2, Bar3)-mkPadsInstance :: UString -> [LString] -> Maybe Type -> [Dec]-mkPadsInstance str args mb@(Nothing)- = buildInst mb str args (ConT ''Pads1 `AppT` TupleT 0)-mkPadsInstance str args mb@(Just ety) - = buildInst mb str args (ConT ''Pads1 `AppT` ety)---- | See 'mkPadsInstance' above.-buildInst mb str args pads =- [ InstanceD Nothing ctx inst [parsePP_method, printFL_method,def_method]- , TySynInstD ''Meta $ TySynEqn [ty_name] meta_ty- , TySynInstD ''PadsArg $ TySynEqn [ty_name] arg_ty- ]- where- arg_ty = case mb of- Nothing -> TupleT 0- Just ety -> ety- mbarg = case mb of- Nothing -> [TupP []]- Just _ -> []- inst = applyT [pads, ty_name, md_ty]- ty_name = applyT (ConT (mkName str) : map fst argpairs)- md_ty = applyT (ConT (mkMDName str) : map snd argpairs)- meta_ty = applyT (ConT (mkMDName str) : metas)- parsePP_method = FunD 'parsePP1 [Clause mbarg (NormalB (applyE (VarE (mkTyParserName str) : [VarE 'parsePP | a <- args]))) []]- printFL_method = - if str == "Entry"- then FunD 'printFL1 [Clause mbarg (NormalB $ VarE $ mkName "undefined") []]- else FunD 'printFL1 [Clause mbarg (NormalB (applyE (VarE (mkTyPrinterName str) : [VarE 'printFL | a <- args]))) []]- def_method = FunD 'def1 [Clause mbarg (NormalB (applyE (VarE (mkTyDefName str) : [VarE 'def | a <- args]))) []]- argpair n = (VarT (mkName n),VarT (mkName $ n++"_md"))- meta n = AppT (ConT ''Meta) (VarT $ mkName n)- argpairs = [argpair a | a <- args]- metas = map meta args- argtyvars = concat [[PlainTV (mkName a), PlainTV (mkName (a++"_md"))] | a <- args]-- ctx = [AppT (AppT (ConT ''Pads) r) m | (r,m) <- argpairs]-- padsprinter t t_md = AppT (ConT ''PadsPrinter) $ appT2 (TupleT 2) t t_md-- printer = case mb of- Nothing -> padsprinter ty_name md_ty- Just ety -> appT2 ArrowT ety (padsprinter ty_name md_ty)----- | Make the following type signatures, applicable for all the forms of a Pads--- declaration:------ > foo_printFL :: (Bar1, Bar2, Bar3) -> PadsPrinter (Foo, Foo_md)--- > foo_def :: (Bar1, Bar2, Bar3) -> Foo------ See 'mkPadsInstance' above for the definition of the Pads type "Foo".-mkPadsSignature :: UString -> [LString] -> Maybe Type -> [Dec]-mkPadsSignature str args mb@(Nothing)- = buildSignature mb str args (ConT ''Pads)-mkPadsSignature str args mb@(Just ety) - = buildSignature mb str args (ConT ''Pads1 `AppT` ety)---- | See 'mkPadsSignature' above.-buildSignature mb str args pads =- if str == "Entry"- then [def_signature]- else [printFL_signature,def_signature]- where- mbarg = case mb of- Nothing -> [TupP []]- Just _ -> []- inst = applyT [pads, ty_name, md_ty]- ty_name = applyT (ConT (mkName str) : map (\(x,y,z) -> y) argpairs)- md_ty = applyT (ConT (mkMDName str) : map (\(x,y,z) -> z) argpairs)- meta_ty = applyT (ConT (mkMDName str) : metas)- argpair n = (VarT (mkName $ n++"_arg"),VarT (mkName n),VarT (mkName $ n++"_md"))- meta n = AppT (ConT ''Meta) (VarT $ mkName n)- argpairs = [argpair a | a <- args]- metas = map meta args- argtyvars = concat [[PlainTV (mkName (a++"_arg")),PlainTV (mkName a), PlainTV (mkName (a++"_md"))] | a <- args]-- printerctx = concat $ [[AppT (ConT ''Data) r, AppT (ConT ''Data) m] | (arg,r,m) <- argpairs]- defctx = concat $ [[AppT (ConT ''Data) r] | (arg,r,m) <- argpairs]-- padsprinter t t_md = AppT (ConT ''PadsPrinter) $ appT2 (TupleT 2) t t_md- padsdef t t_md = t-- printer = case mb of- Nothing -> padsprinter ty_name md_ty- Just ety -> appT2 ArrowT ety (padsprinter ty_name md_ty)- def = case mb of- Nothing -> padsdef ty_name md_ty- Just ety -> appT2 ArrowT ety (padsdef ty_name md_ty)-- printFL_signature = SigD (mkTyPrinterName str) $ ForallT argtyvars printerctx $ foldr (\a t -> let (a_arg,a_rep,a_md) = argpair a in appT2 ArrowT (padsprinter a_rep a_md) t) printer args- def_signature = SigD (mkTyDefName str) $ ForallT argtyvars defctx $ foldr (\a t -> let (a_arg,a_rep,a_md) = argpair a in appT2 ArrowT (padsdef a_rep a_md) t) def args------------------------------------------------------------------------------------ * Generating Parser Declaration from Type / Data / New Declarations---- | Construct the function body and resulting declaration of the "_parseM"--- function for a given 'PadsTy' type declaration.-genPadsParseM :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]-genPadsParseM name args patM padsTy = do - let body = genParseTy padsTy- mkParserFunction name args patM body---- | 'PadsData' data declaration flavour of the "_parseM" function.-genPadsDataParseM :: UString -> [LString] -> (Maybe Pat) -> PadsData -> Q [Dec] -genPadsDataParseM name args patM padsData = do - let body = genParseData padsData- mkParserFunction name args patM body---- | 'BranchInfo' new type declaration flavour of the "_parseM" function.-genPadsNewParseM :: UString -> [LString] -> (Maybe Pat) -> BranchInfo -> Q [Dec] -genPadsNewParseM name args patM branch = do - (dec,exp) <- genParseBranchInfo branch- let body = letE [return dec] (return exp)- mkParserFunction name args patM body---- | Pads Obtain declaration flavour of the "_parseM" function.-genPadsObtainParseM :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]-genPadsObtainParseM name args padsTy exp = do- let body = genParseTy (PTransform padsTy (PTycon [name]) exp)- mkParserFunction name args Nothing body---- | Construct the declaration for a function which monadically parses a Pads--- type given the body of the function as input.-mkParserFunction :: UString -> [LString] -> Maybe Pat -> Q Exp -> Q [Dec]-mkParserFunction name args patM body- = sequence $ if name == "Entry" then [sig,fun] else [fun]- where- fun = funD parserName [clause parserArgs (normalB body) []]- sig = sigD parserName [t| PadsParser ($(conT $ mkConstrName name), (Base_md, $(conT $ mkConstrIMDName name))) |]- parserName = mkTyParserName name- parserArgs = map (varP . mkVarParserName) args ++ Maybe.maybeToList (return <$> patM)------------------------------------------------------------------------------------ * Generating String-Parser Declaration---- | Construct the "_parseS" function at compile time such that it makes a call--- to 'parseStringInput' at runtime.-genPadsParseS :: UString -> [LString] -> Maybe Pat -> Q [Dec]-genPadsParseS name args patM = do - { body <- [| parseStringInput $(return parserWithArgs) |]- ; return [ FunD (mkTyParserSName name) [Clause parserArgs (NormalB body) []] ]- }- where- parserWithArgs = foldl1 AppE (VarE parserName : map patToExp parserArgs)- parserName = mkTyParserName name - parserArgs = map (VarP . mkVarParserName) args ++ Maybe.maybeToList patM------------------------------------------------------------------------------------ * Generating Parser from Type Expression---- | This function only ever gets called at compile time in order to construct a--- template haskell expression to be used somewhere in the body of a "_parseM"--- function. This expression is the meat of the pads-haskell parsing algorithm--- and semantics - we use metaprogramming to map the Pads syntax onto--- expressions which return a tuple consisting of the parsed representation--- followed by the metadata (with parse errors).-genParseTy :: PadsTy -> Q Exp-genParseTy pty = case pty of- PConstrain pat ty exp -> genParseConstrain (return pat) ty (return exp)- PTransform src dest exp -> genParseTyTrans src dest (return exp)- PList ty sep term -> genParseList ty sep term- PPartition ty exp -> genParsePartition ty exp- PValue exp ty -> genParseValue exp- PApp tys argE -> genParseTyApp tys argE- PTuple tys -> genParseTuple tys- PExpression exp -> genParseExp exp- PTycon c -> return $ mkParseTycon c- PTyvar v -> return $ mkParseTyvar v---- | Simply generate a call to the runtime system function 'parseConstraint'--- where the first argument is a Haskell expression spliced directly into the--- call to 'parseConstraint' which parses the thing being constrained and the--- second argument is the (Haskell) predicate function used to constrain the--- Pads type.-genParseConstrain :: Q Pat -> PadsTy -> Q Exp -> Q Exp-genParseConstrain patQ ty expQ = [| parseConstraint $(genParseTy ty) $pred |]- where- pred = lamE [patQ, varP (mkName "md")] expQ---- | Simply generate a call to the runtime system function 'parseTransform'--- where the first argument is the spliced-in-place parser for the "source" Pads--- type being transformed and the second argument is the (Haskell)--- transformation function for producing something of the desired destination--- type. Note that we can ignore the destination 'PadsTy' at compile time in--- *this* function because the Haskell type checker will type check the result--- of 'parseTransform' for us.-genParseTyTrans :: PadsTy -> PadsTy -> Q Exp -> Q Exp-genParseTyTrans src dest expQ- = [| parseTransform $(genParseTy src) (fst $expQ) |]---- | This compile time function figures out which runtime system support--- function to generate a call to for parsing a Pads list type based on the--- given separator Pads type and the desired termination condition 'TermCond'.-genParseList :: PadsTy -> (Maybe PadsTy) -> (Maybe TermCond) -> Q Exp-genParseList ty sep term =- case (sep,term) of - (Nothing, Nothing) -> [| parseListNoSepNoTerm $(genParseTy ty) |]- (Just sep, Nothing) -> [| parseListSepNoTerm $(genParseTy sep) $(genParseTy ty) |]- (Nothing, Just (LLen lenE)) -> [| parseListNoSepLength $(return lenE) $(genParseTy ty) |]- (Just sep, Just (LLen lenE)) -> [| parseListSepLength $(genParseTy sep) $(return lenE) $(genParseTy ty) |]- (Nothing, Just (LTerm term))-> [| parseListNoSepTerm $(genParseTy term) $(genParseTy ty) |]- (Just sep, Just (LTerm term))-> [| parseListSepTerm $(genParseTy sep) $(genParseTy term) $(genParseTy ty) |]---- | Simply generate a call to the runtime system function 'parsePartition'--- where the first argument is an expression for parsing the 'PadsTy' pads type--- we're partitioning on and the second argument is the Haskell expression given--- in the Pads syntactic form specifying the record discipline with which to--- partition things. For example the following code:------ > type Foo = (partition [Bar] using none)------ declares a type Foo which is a list of Bars where Bars are separated by--- nothing.-genParsePartition :: PadsTy -> Exp -> Q Exp-genParsePartition ty disc = [| parsePartition $(genParseTy ty) $(return disc) |]---- | This compile time function generates code which wraps a Pads Value type's--- Haskell expression in the appropriate type to be returned for use in the pads--- parsing monad, namely of type 'PadsParser (rep, md)' where rep and md are the--- representation and metadata type variables.-genParseValue :: Exp -> Q Exp-genParseValue exp = [| return ($(return exp), cleanBasePD) |]---genParseValue exp = return $ AppE (VarE 'return) (TupE [exp,VarE 'cleanBasePD])---- | Construct the sequentially-defined parser for a Pads tuple type.-genParseTuple :: [PadsTy] -> Q Exp-genParseTuple [] = [| return ((), cleanBasePD) |]-genParseTuple tys = do- f_rep_name <- newName "f_rep"- f_md_name <- newName "f_md"- let f_rep = buildF_rep f_rep_name vars_frep- f_rep_sig = buildF_rep_sig f_rep_name sigs_frep- f_md = buildF_md f_md_name vars_fmd- f_md_sig <- buildF_md_sig f_md_name tys- body <- foldl parseNext [| return ($(dyn "f_rep"),$(dyn "f_md")) |] tys- return (LetE [f_rep_sig,f_rep,f_md_sig,f_md] body)- where- vars_frep = [v | (v,t) <- zip vars_fmd tys, hasRep t]- sigs_frep = [t | t <- tys, hasRep t]- vars_fmd = [ mkName ("x"++show n) | n <- [1 .. length tys]] ---- | Glom the generated parser for the given 'PadsTy' onto the given parser--- using the '=@=' and '=@' runtime system operators.-parseNext :: Q Exp -> PadsTy -> Q Exp-parseNext prog t- | hasRep t = [| $prog =@= $(genParseTy t) |]- | otherwise = [| $prog =@ $(genParseTy t) |]---- | Construct the "f_rep" let-bound function inside of a Pads tuple type for--- uncurrying the result of parsing the tuple sequentially at runtime. The--- "f_rep" function generated by *this* function gets passed into the '=@=' and--- '=@' runtime system operators which call f_rep on the result of parsing each--- of the members of the tuple.-buildF_rep :: Name -> [Name] -> Dec-buildF_rep name vars_frep- = FunD name [Clause- (map VarP vars_frep) (NormalB (TupE (map VarE vars_frep))) [] ]--isVarT (VarT _) = True-isVarT _ = False--buildF_md_sig :: Name -> [PadsTy] -> Q Dec-buildF_md_sig name ptys = do- let tys = map (mkMDTy False) ptys- mdRet = foldl AppT (TupleT $ length tys) tys- retTy <- [t| (Base_md, $(return mdRet)) |]- let sigTy = foldr1 (appT2 ArrowT) (tys ++ [retTy])- varTs = filter isVarT tys- varTNames = map (\(VarT t) -> PlainTV t) varTs- sigT' = ForallT varTNames (map (AppT (ConT ''PadsMD)) varTs) sigTy- return (case tys of- [] -> SigD name $ TupleT 0- (t:[]) -> SigD name $ appT2 ArrowT t t- _ -> SigD name $ sigT')---- | Same as 'buildF_rep' above but for the metadata instead of the parse--- representation. In this case we need to pull off just the 'Base_md' from the--- metadata resulting from whatever the parser returned to us for each of the--- tuple results using the 'get_md_header' type class function provided by the--- runtime system.-buildF_md :: Name -> [Name] -> Dec-buildF_md f_md_name vars_fmd- = FunD f_md_name [Clause (map VarP vars_fmd) (NormalB body) []]- where- mdHeaders = [ VarE 'get_md_header `AppE` VarE xi | xi <- vars_fmd ]- body = TupE [mkMergeBaseMDs mdHeaders, TupE (map VarE vars_fmd)]--buildF_rep_sig :: Name -> [PadsTy] -> Dec-buildF_rep_sig name ptys = let- tys = map mkRepTy ptys- retTy = foldl AppT (TupleT $ length tys) tys- sigTy = foldr1 (appT2 ArrowT) (tys ++ [retTy])- in (case tys of- [] -> SigD name $ TupleT 0- (t:[]) -> SigD name $ appT2 ArrowT t t- _ -> SigD name $ sigTy)---- | Generate a call to 'mergeBaseMDs'-mkMergeBaseMDs :: [Exp] -> Exp-mkMergeBaseMDs [e] = e-mkMergeBaseMDs es = VarE 'mergeBaseMDs `AppE` ListE es---- | Construct a call to the 'litParse' runtime system type class function so--- that we can parse a literal (Haskell) expression. The type of the expression--- provided as a Haskell expression must be Literally Parseable ('LitParse' type--- class), otherwise the code generated by *this* compile time function produces--- a type error.-genParseExp :: Exp -> Q Exp-genParseExp exp = [| litParse $(return exp) |]---- | Generate the parser for a Pads type application.-genParseTyApp :: [PadsTy] -> Maybe Exp -> Q Exp-genParseTyApp tys expM = do- fs <- mapM genParseTy tys- return (foldl1 AppE (fs ++ Maybe.maybeToList expM))---- | Make the parser for a Pads type constructor - just return it as a Haskell--- variable expression.-mkParseTycon :: QString -> Exp-mkParseTycon ["EOF"] = VarE 'eof_parseM-mkParseTycon ["EOR"] = VarE 'eor_parseM-mkParseTycon c = VarE (mkTyParserQName c)---- | Make the parser for a Pads type variable - just return it as a Haskell--- variable expression.-mkParseTyvar :: String -> Exp-mkParseTyvar v = VarE (mkVarParserName v) -- should gensym these, but probably ok------------------------------------------------------------------------------------ * Generating Parsers from Union/Switch Expressions---- | A data declaration in pads is either a union or a switch expression ---- generate the template haskell for parsing them.-genParseData :: PadsData -> Q Exp-genParseData (PUnion bs) = genParseUnion bs-genParseData (PSwitch exp pbs) = genParseSwitch exp pbs---- | Generate the template haskell for parsing a Pads union expression. Namely--- generate the metadata constructors for each of the branches of the union and--- stuff them into let-bound functions so that nested parsers have them in--- scope. Then generate a call to the runtime system function 'choiceP' for--- choosing among the different parsers.-genParseUnion :: [BranchInfo] -> Q Exp-genParseUnion bs = do- { (decs,bodies) <- fmap unzip $ mapM genParseBranchInfo bs- ; let body = case bodies of- [b] -> b- bs -> (VarE 'choiceP) `AppE` (ListE bs)- ; return (LetE decs body)- }---- | Generate the template haskell case expression from a Pads switch type. This--- is almost entirely just matching the syntax of a Pads case onto the syntax of--- a Haskell case expression. Semantically the case just figures out which--- parser needs to be run by pattern matching on something already parsed from--- the input.-genParseSwitch :: Exp -> [(Pat,BranchInfo)] -> Q Exp-genParseSwitch exp pbs = do- let (ps,bs) = unzip pbs- (decs,bodies) <- fmap unzip $ mapM genParseBranchInfo bs- let body = CaseE exp [Match p (NormalB b) [] | (p,b) <- zip ps bodies]- return (LetE decs body)---- | Generate the parser for an individual branch of a Pads new type, Pads--- union, or Pads switch.-genParseBranchInfo :: BranchInfo -> Q (Dec,Exp)-genParseBranchInfo (BRecord c fields pred) = genParseRecord c fields pred-genParseBranchInfo (BConstr c args pred) = do- { body <- foldl parseNext [| return ($(conE (mkConstrName c)),$(varE (mkfnMDName c))) |] tys- ; return (con_md, body)- }- where- tys = [ty | (strict,ty) <- args]- con_md = buildConstr_md (mkfnMDName c) (ConE (mkConstrIMDName c)) tys---- | Build the constructor function for tupling together the metadata results of--- parsing a bunch of Pads types.-buildConstr_md :: Name -> Exp -> [PadsTy] -> Dec-buildConstr_md fnMD conMD tys - = FunD fnMD [Clause (map VarP vars_fmd) (NormalB body) []]- where- vars_fmd = [ mkName ("x"++show n) | n <- [1 .. length tys]] - mdHeaders = [ VarE 'get_md_header `AppE` VarE xi | xi <- vars_fmd ]- body = TupE [mkMergeBaseMDs mdHeaders, applyE (conMD : map VarE vars_conmd)]- vars_conmd = vars_fmd --MD [v | (v,t) <- zip vars_fmd tys, hasRep t]------------------------------------------------------------------------------------ * Generating Parsers from Record Expressions---- | Generate the template haskell code for parsing a Pads record.-genParseRecord :: UString -> [FieldInfo] -> (Maybe Exp) -> Q (Dec,Exp)-genParseRecord c fields pred = do- c_md <- newName (strToLower c)- let con_md = buildConstr_md c_md (ConE (mkConstrIMDName c))- [ty | (_,(_,ty),_) <- fields]- labMDs <- sequence [genLabMDName "x" l | (l,(_,_),_) <- fields] - let fnMDLabs = applyE $ map VarE (c_md : labMDs)- doStmts <- sequence $ [genParseField f xn | (f,xn) <- zip fields labMDs]- let labs = [mkName lab | (Just lab,(_,ty),_) <- fields, hasRep ty]- let conLabs = applyE (ConE (mkConstrName c) : map VarE labs)- returnStmt <- [| return ($(return conLabs),$(return fnMDLabs)) |]- return (con_md, DoE (concat doStmts ++ [NoBindS returnStmt]))---- | Generate the name (label?) for the metadata of a field in a record.-genLabMDName :: String -> Maybe String -> Q Name-genLabMDName s (Just lab) = return (mkFieldMDName lab)-genLabMDName s Nothing = liftM mangleName (newName s)---- | Generate the parser for a field of a Pads record.-genParseField :: FieldInfo -> Name -> Q [Stmt]-genParseField (labM, (strict, ty), expM) xn = do- let parseTy = (case expM of - Nothing -> genParseTy ty- Just exp -> genParseRecConstrain labP (varP xn) ty (return exp))- sequence $- [ bindS (tupP [labP, varP xn]) parseTy- ]- where- labP = case labM of- Just lab -> varP (mkName lab)- Nothing -> wildP---- | Generate the parser for a constrained field on a record.-genParseRecConstrain :: Q Pat -> Q Pat -> PadsTy -> Q Exp -> Q Exp-genParseRecConstrain labP xnP ty exp = [| parseConstraint $(genParseTy ty) $pred |]- where- pred = lamE [labP, xnP] exp------------------------------------------------------------------------------------ Generating Printing Function from a Declaration---- | Generate the lazy "function list" printer for a given 'PadsTy' Pads type as--- parsed using Pads' plain-type syntactic form..-genPadsPrintFL :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]-genPadsPrintFL name args patM padsTy = do - let rm = [mkName "rep", mkName "md"]- body <- genPrintTy padsTy $ Just $ TupE (map VarE rm)- return [mkPrinterFunction name args rm patM body]---- | Generate the lazy function list printer for the Pads data-type syntactic--- form.-genPadsDataPrintFL :: UString -> [LString] -> Maybe Pat -> PadsData -> Q [Dec] -genPadsDataPrintFL name args patM padsData = do- let rm = [mkName "rep", mkName "md"]- body <- genPrintData padsData $ Just $ TupE (map VarE rm)- return [mkPrinterFunction name args rm patM body]---- | Generate the lazy function list printer for the Pads newtype syntactic form.-genPadsNewPrintFL :: UString -> [LString] -> Maybe Pat -> BranchInfo -> Q [Dec] -genPadsNewPrintFL name args patM branch = do - let rm = [mkName "rep", mkName "md"]- matches <- genPrintBranchInfo False branch- let body = CaseE (TupE (map VarE rm)) matches- return [mkPrinterFunction name args rm patM body]---- | Generate the lazy function list printer for the Pads obtain syntactic form.-genPadsObtainPrintFL :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]-genPadsObtainPrintFL name args padsTy exp = do- let rm = [mkName "rep", mkName "md"]- body <- genPrintTy (PTransform padsTy (PTycon [name]) exp) $ Just $ TupE (map VarE rm)- return [mkPrinterFunction name args rm Nothing body]---- | Make the function declaration for the "lazy function list" printer with the--- body as generated by 'genPrintTy', 'genPrintData', or 'genPrintBranchInfo' as--- passed into this function as the last 'Exp' parameter.-mkPrinterFunction :: UString -> [LString] -> [Name] -> Maybe Pat -> Exp -> Dec-mkPrinterFunction name args rm patM body =- FunD printerName [Clause (printerArgs ++ [TupP (map VarP rm)]) (NormalB body) []]- where- printerName = mkTyPrinterName name- printerArgs = map (VarP . mkTyPrinterVarName) args ++ Maybe.maybeToList patM------------------------------------------------------------------------------------ * Generate Printing Function from a Type---- | Generate the body of the printing function for a Pads type - this function--- dispatches to the ones below according to the syntactic form being--- translated.-genPrintTy :: PadsTy -> Maybe Exp -> Q Exp-genPrintTy (PConstrain pat ty exp) rm = genPrintTy ty rm -- XXX: doesn't check the constraint; ideally we should change @printFL@ to account for possible printing errors-genPrintTy (PTransform src dest exp) rm = genPrintTrans src exp rm-genPrintTy (PList ty sepM termM) rm = genPrintList ty sepM termM >>= applyPrintTy rm-genPrintTy (PPartition ty exp) rm = [| (error "genPrintTy PPartition not implemented") |] --genPrintPartition ty exp rm-genPrintTy (PApp tys expM) rm = genPrintTyApp tys expM >>= applyPrintTy rm-genPrintTy (PTuple tys) rm = genPrintTuple tys rm-genPrintTy (PExpression exp) rm = genPrintExp exp rm-genPrintTy (PTycon c) rm = genPrintTycon c >>= applyPrintTy rm-genPrintTy (PTyvar v) rm = genPrintTyVar v >>= applyPrintTy rm-genPrintTy (PValue exp ty) rm = genPrintValue exp rm---- | Generate the printer for the Pads Value syntactic form 'PValue'. Because a--- pads value is something that wasn't parsed (it's a way to compute / add an extra--- field to a parsed Haskell record), we just return the 'nil' printer (prints--- nothing).-genPrintValue :: Exp -> Maybe Exp -> Q Exp-genPrintValue exp rm = return $ VarE 'nil---- | Generate the printer for the Pads Transform syntactic form 'PTransform'.--- This means we need to grab the second function from the tuple provided by the--- Pads programmer which corresponds to the inverse of the transform function,--- and print the format of the resulting (source) type. Source here means what's--- read from a file and destination type means the type for which we have a--- value that we want to print out. In order for round-trip parsing to work, we--- need to reverse the transformation because the on-disk format of the source--- type is usually different from the on-disk format of the destination type.-genPrintTrans :: PadsTy -> Exp -> Maybe Exp -> Q Exp-genPrintTrans tySrc exp Nothing- = genPrintTy tySrc Nothing-genPrintTrans tySrc (TupE [_, fncn]) (Just rm) = do- rm' <- [| $(return fncn) $(return rm) |]- genPrintTy tySrc (Just rm')-genPrintTrans _ tup _ = error ("Template Haskell exp '" ++ show tup ++ "' does not appear to be a two-tuple.")---- | Some of the printing utilities provided by the runtime system need to know--- about the representation and the metadata. If the first argument to this--- function is Nothing, then we don't need to pass the representation and--- metadata to the expression / utility (e.g. ca case expression printing a--- union type). Otherwise the first argument contains 'Just' the '(rep, md)'--- tuple brought into scope as the first parameter to the "*_printFL" functions--- (e.g. the 'printList' runtime system function needs to know about the rep and--- md).-applyPrintTy :: Maybe Exp -> Exp -> Q Exp-applyPrintTy rm f = do- case rm of- Nothing -> return f- Just repmdE -> return $ AppE f repmdE---- | Generate the template haskell code for printing a 'PList' Pads type.-genPrintList :: PadsTy -> Maybe PadsTy -> Maybe TermCond -> Q Exp-genPrintList ty sepOpt termCondOpt = do - (elemRepE, elemRepP) <- doGenPE "elemrep"- (elemMDE, elemMDP) <- doGenPE "elemmd"- parseElemE <- genPrintTy ty $ Just $ TupE [elemRepE,elemMDE]- let parseElemFnE = LamE [TupP [elemRepP, elemMDP]] parseElemE- sepElemE <- case sepOpt of - Nothing -> return (VarE 'printNothing)- Just ty -> do- def <- genDefTy ty- genPrintTy ty $ Just $ TupE [SigE def (mkRepTy ty),SigE (VarE 'myempty) (mkMDTy False ty)]- termElemE <- case termCondOpt of- Nothing -> return (VarE 'printNothing)- Just (LLen _) -> return (VarE 'printNothing)- Just (LTerm (PApp [PTycon ["Try"],_] _)) -> return (VarE 'printNothing)- Just (LTerm (PTuple [PApp [PTycon ["Try"],_] _])) -> return (VarE 'printNothing)- Just (LTerm termTy) -> do- def <- genDefTy termTy- genPrintTy termTy $ Just $ TupE [SigE def (mkRepTy termTy),SigE (VarE 'myempty) (mkMDTy False termTy)]- return $ appE3 (VarE 'printList) parseElemFnE sepElemE termElemE---- | Generate the template haskell code for printing a Pads type application by--- recursively calling 'genPrintTy' on the Pads types of each of the arguments to the--- Pads type constructor.-genPrintTyApp :: [PadsTy] -> Maybe Exp -> Q Exp-genPrintTyApp tys expM = do- prtys <- mapM (flip genPrintTy Nothing) tys- foldl1M (\e1 e2 -> return $ AppE e1 e2) (prtys ++ Maybe.maybeToList expM)---- | Generate the template haskell code for printing a Pads tuple type.-genPrintTuple :: [PadsTy] -> Maybe Exp -> Q Exp-genPrintTuple tys (Just rm) = do- repNamesM <- genNamesforTuple True "rep" tys- let repVars = map VarE (Maybe.catMaybes repNamesM)- let repPats = map VarP (Maybe.catMaybes repNamesM)- mdNamesM <- genNamesforTuple False "md" tys- let mdVars = map VarE (Maybe.catMaybes mdNamesM)- let mdPats = map VarP (Maybe.catMaybes mdNamesM)- inners <- sequence [genPrintTupleInner t r m | (t,r,m) <- zip3 tys repNamesM mdNamesM{-, hasRep t-}]- return $ CaseE rm- [Match (TupP [TupP $ repPats, TupP [SigP WildP (ConT ''Base_md), (TupP mdPats)]]) - (NormalB (VarE 'concatFL `AppE` ListE inners))- []]-genPrintTuple tys Nothing = do- repName <- newName "rep"- mdName <- newName "md"- liftM (LamE [TupP [VarP repName,VarP mdName]]) $ genPrintTuple tys $ Just $ TupE [VarE repName,VarE mdName]---- | Filters a second list based on which corresponding Pads types from the--- first list have an underlying representation in memory (removing the ones--- that don't have an underlying representation).-filterByHasRep :: [PadsTy] -> [a] -> [a]-filterByHasRep tys xs = map snd $ filter (hasRep . fst) (zip tys xs)---- | Generate a list of names to be used as Haskell pattern variables and--- expression variables for a Pads tuple type. If the tuple is for the--- representation then the given 'Bool' is True and we want to ignore data that--- doesn't have a representation in memory. Otherwise the tuple is for the--- metadata meaning the given 'Bool' is False and we want to print *everything*.-genNamesforTuple :: Bool -> String -> [PadsTy] -> Q [Maybe Name]-genNamesforTuple False str tys = sequence [fmap Just (newName str) | ty <- tys]-genNamesforTuple True str tys = sequence [if hasRep ty then fmap Just (newName str) else return Nothing | ty <- tys]---- | Generate the template haskell print function for some type inside of a--- tuple based on whether or not that type has an in-memory representation--- '(Just r)' and a metadata representation '(Just m)'.-genPrintTupleInner t (Just r) (Just m) = genPrintTy t (Just (TupE [VarE r,VarE m])) -genPrintTupleInner t Nothing (Just m) = genDefTy t >>= \def -> genPrintTy t (Just (TupE [def, VarE m]))-genPrintTupleInner t Nothing Nothing = genPrintTy t Nothing-genPrintTupleInner t (Just r) Nothing = error ("genPrintTupleInner: Type '" ++ show t- ++ "' has a representation but no metadata.")---- | Generate the template haskell code for printing the value of a Pads literal--- (string, character, regex) by simply constructing a runtime system call to--- 'litPrint' with the code for computing the Haskell value of the literal--- spliced into the first argument position.-genPrintExp :: Exp -> Maybe Exp -> Q Exp-genPrintExp e _ = [| litPrint $(return e) |]---- | Generate the printer for a Pads type constructor (hint: it's just the--- variable name according to 'mkTyPrinterQName'.-genPrintTycon :: QString -> Q Exp-genPrintTycon c = return $ VarE (mkTyPrinterQName c)---- | Generate the printing expression for a Pads type variable according to--- 'mkTyPrinterVarName'.-genPrintTyVar :: LString -> Q Exp-genPrintTyVar v = return $ VarE (mkTyPrinterVarName v)------------------------------------------------------------------------------------ Generate Printing Function from a Datatype---- | Generate the template haskell expression for printing a Haskell value given--- the Pads data type declaration defining the type of the Haskell value.-genPrintData :: PadsData -> Maybe Exp -> Q Exp-genPrintData (PUnion bs) rm = genPrintUnion bs rm-genPrintData (PSwitch exp pbs) rm = genPrintSwitch exp pbs rm---- | Generate a Haskell case expression for printing a Pads union type.-genPrintUnion :: [BranchInfo] -> Maybe Exp -> Q Exp-genPrintUnion bs (Just rm) = do- let doDef = if length bs > 1 then True else False- matches <- liftM concat $ mapM (genPrintBranchInfo doDef) bs- return $ CaseE rm matches-genPrintUnion bs Nothing = do- repName <- newName "rep"- mdName <- newName "md"- let doDef = if length bs > 1 then True else False- matches <- liftM concat $ mapM (genPrintBranchInfo doDef) bs- return $ LamE [TupP [VarP repName,VarP mdName]] $ CaseE (TupE [VarE repName,VarE mdName]) matches---- | Generate the printing function body of an individual branch of a Pads data type.-genPrintBranchInfo :: Bool -> BranchInfo -> Q [Match]-genPrintBranchInfo doDef (BRecord c fields predM) = genPrintRecord c fields predM-genPrintBranchInfo doDef (BConstr c args predM) = genPrintConstr doDef c args predM---- | Generate the individual 'Match' of the Haskell case expression for matching--- on a record being printed.-genPrintRecord :: UString -> [FieldInfo] -> Maybe Exp -> Q [Match]-genPrintRecord (mkName -> recName) fields predM = do - (repEs, repPs) <- getPEforFields (\t -> genDefTy t >>= \def -> return $ SigE def (mkRepTy t)) (return . getBranchNameL) fields- (mdEs, mdPs) <- getPEforFields (return . SigE (VarE 'myempty) . mkMDTy False) (return . getBranchMDNameL) fields- let ptys = map (\(n,(_,ty),p) -> ty) fields- let ty_rep_mds = zip3 ptys repEs mdEs- expE <- mapM (\(ty,r,m) -> genPrintTy ty $ Just $ TupE [r,m]) ty_rep_mds- let printItemsE = ListE expE- let caseBody = NormalB (AppE (VarE 'concatFL) printItemsE)- let mdPat = TupP[WildP, RecP (getStructInnerMDName recName) mdPs]- let repPat = RecP recName repPs- let casePat = TupP [repPat, mdPat]- let match = Match casePat caseBody []- return [match]---- | Get the printer expression for an individual field of a record.-getPEforField :: (PadsTy -> Q Exp) -> (String -> Q Name) -> FieldInfo -> Q (Exp, Maybe FieldPat)-getPEforField def mkFieldNm (nameOpt, (strict,pty), optPred) = case nameOpt of- Nothing -> def pty >>= \d -> return (d,Nothing)- Just str -> do- name <- mkFieldNm str- let (varE, varP) = genPE name- return (varE, Just (name, varP))---- | Get the printer expressions and corresponding record field pattern--- matches for each of the given 'FieldInfo's.-getPEforFields :: (PadsTy -> Q Exp) -> (String -> Q Name) -> [FieldInfo] -> Q ([Exp], [FieldPat])-getPEforFields def mkFieldNm fields = do- eps <- mapM (getPEforField def mkFieldNm) fields- let (es, pOpts) = List.unzip eps- ps = Maybe.catMaybes pOpts- return (es, ps)---- | Generate the template haskell code for matching on and printing the value--- for a Pads value constructor.-genPrintConstr :: Bool -> String -> [ConstrArg] -> (Maybe Exp) -> Q [Match]-genPrintConstr doDef (mkName -> recName) args predM = do- let fields = map (\c -> (Just "arg",c,Nothing)) args- (repEs, repPs) <- getPEforFields (\t -> genDefTy t >>= \def -> return $ SigE def (mkRepTy t)) newName fields- (mdEs, mdPs) <- getPEforFields (return . SigE (VarE 'myempty) . mkMDTy False) newName fields- let ptys = map (\(n,(s,ty),p) -> ty) fields-- let genBody mdEs = (do- { let genTyRepMd = (\(ty,r,m) -> if hasRep ty then return (ty,r,m) else genDefTy ty >>= (\def -> return (ty,SigE def (mkRepTy ty),m)))- ; ty_rep_mds <- mapM genTyRepMd $ zip3 ptys repEs mdEs- ; expE <- mapM (\(ty,repE,mdE) -> genPrintTy ty $ Just $ TupE [repE,mdE]) ty_rep_mds- ; let printItemsE = ListE expE- ; let caseBody = NormalB (AppE (VarE 'concatFL) printItemsE)- ; return caseBody- })-- let repPat = ConP recName (filterByHasRep ptys $ map snd repPs) - let mdPat = TupP[SigP WildP (ConT ''Base_md), ConP (getStructInnerMDName recName) (map snd mdPs)]-- caseBody <- genBody mdEs- let match = Match (TupP [repPat, mdPat]) caseBody []-- caseBodyDef <- genBody $ map (\(_,ty) -> SigE (VarE 'myempty) (mkMDTy False ty)) args- let matchDef = Match (TupP [repPat,WildP]) caseBodyDef []- if doDef then return [match,matchDef] else return [match]---- | Generate the template haskell code for printing a Pads switch type by--- ignoring the value we're switching on and simply generating the same case--- expression that 'genPrintUnion' does for a Pads union type.-genPrintSwitch :: Exp -> [(Pat,BranchInfo)] -> Maybe Exp -> Q Exp-genPrintSwitch exp pbs rm = genPrintUnion (map snd pbs) rm------------------------------------------------------------------------------------ * Generating Default Function from a Declaration---- | Generate the Pads default value for a 'PadsDeclType'-genPadsDef :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]-genPadsDef name args patM padsTy = do - body <- genDefTy padsTy- return [mkDefFunction name args patM body]---- | Generate the Pads default value for a Pads data declaration.-genPadsDataDef :: UString -> [LString] -> Maybe Pat -> PadsData -> Q [Dec] -genPadsDataDef name args patM padsData = do- body <- genDefData padsData- return [mkDefFunction name args patM body]---- | Generate the Pads default value for a Pads newtype declaration.-genPadsNewDef :: UString -> [LString] -> Maybe Pat -> BranchInfo -> Q [Dec] -genPadsNewDef name args patM branch = do - body <- genDefBranchInfo branch- return [mkDefFunction name args patM body]---- | Generate the Pads default value for a Pads obtain declaration.-genPadsObtainDef :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]-genPadsObtainDef name args padsTy exp = do- body <- genDefTy (PTransform padsTy (PTycon [name]) exp)- return [mkDefFunction name args Nothing body]---- | Generate the Pads default value as a function declaration of the form--- "foo_def" for a Pads parser named "Foo".-mkDefFunction :: UString -> [LString] -> Maybe Pat -> Exp -> Dec-mkDefFunction name args patM body =- FunD defName [Clause (defArgs) (NormalB body) []]- where- defName = mkTyDefName name- defArgs = map (VarP . mkTyDefVarName) args ++ Maybe.maybeToList patM------------------------------------------------------------------------------------ * Generate Default Function from a Type---- | Generate the default Haskell value for some Pads type.-genDefTy :: PadsTy -> Q Exp-genDefTy (PConstrain pat ty exp) = genDefTy ty -- XXX: doesn't check the constraint; ideally we should change @printFL@ to account for possible printing errors-genDefTy (PTransform src dest exp) = do- defSrc <- genDefTy src- srcToDest <- [| \rep -> fst $ (fst $(return exp)) S.zeroSpan (rep,(error "TODO defaultMd")) |] -- XXX: fix this undefined, it kind of requires defaultMd to be defined inductively over Pads types as well...- return $ AppE srcToDest defSrc-genDefTy (PList ty sepM termM) = [| [] |]-genDefTy (PPartition ty exp) = genDefTy ty-genDefTy (PApp tys expM) = do- prtys <- mapM genDefTy tys- foldl1M (\e1 e2 -> return $ AppE e1 e2) (prtys ++ Maybe.maybeToList expM)-genDefTy (PTuple tys) = genDefTuple tys-genDefTy (PExpression exp) = return exp-genDefTy (PTycon c) = return $ VarE (mkTyDefQName c)-genDefTy (PTyvar v) = return $ VarE (mkTyDefVarName v)-genDefTy (PValue exp ty) = genDefTy ty---- | Generate the default Haskell value for a Pads tuple type.-genDefTuple :: [PadsTy] -> Q Exp-genDefTuple tys = case reps of- [] -> [| () |]- [ty] -> genDefTy ty- tys -> do- exps <- mapM genDefTy tys- return $ TupE exps- where- reps = [ty | ty <- tys, hasRep ty]------------------------------------------------------------------------------------ Generate Default Function from a Datatype---- | Generate the default Haskell value for a Pads data type 'PadsData'.-genDefData :: PadsData -> Q Exp-genDefData (PUnion (b:bs)) = genDefBranchInfo b-genDefData (PSwitch exp (pb:pbs)) = genDefBranchInfo (snd pb)-genDefData (PUnion []) = error "genDefData: empty PUnion."-genDefData (PSwitch exp []) = error "genDefData: empty PSwitch."---- | Generate the default Haskell value for a single branch of a Pads type,--- namely either a Pads constructor or record.-genDefBranchInfo :: BranchInfo -> Q Exp-genDefBranchInfo (BConstr c args pred) = do- reps <- sequence $ [genDefTy ty | (strict,ty) <- args, hasRep ty]- return $ foldl1 AppE (ConE (mkConstrName c):reps)-genDefBranchInfo (BRecord c fields expM) = do- reps <- sequence $ [liftM (l,) (genDefTy ty) | (Just l,(strict,ty),_) <- fields, hasRep ty]-- let lets = flip map reps $ \(lab,def) -> ValD (VarP $ mkName lab) (NormalB def) []- return $ LetE lets $ foldl1 AppE (ConE (mkConstrName c):map (VarE . mkName . fst) reps)------------------------------------------------------------------------------------ * Name Manipulation Functions ---- ** Naming types, and accessing the names of types---- | Get the template haskell 'Name' for a given Pads type.-mkRepName :: String -> Name-mkRepName str = mkName str---- | Make the template haskell 'Name' of a given 'PTycon' with a qualified name.-mkRepQName :: QString -> Name-mkRepQName str = mkName (qName str)---- | Make externally visible metadata name for a Pads type-mkMDName :: String -> Name-mkMDName str = mkName (str ++ "_md")---- | Given a Pads type name in the template haskell @Q@ monad, get the metadata--- type name.-mkMDQName :: QString -> Name-mkMDQName str = mkName (appendTo str "_md")---- | Make the internal metadata type name for a given Pads type-mkIMDName name = mkName (name ++ "_imd")---- | Make externally visible metadata name for a Pads variable-mkMDVarName name = mkName (name ++ "_md")---- ** Naming fields and constructors---- | Convert Pads source (record) field name into a 'Q' monad name-mkFieldName str = mkName str---- | Convert Pads source (record) field name into its metadata name in the 'Q'--- monad.-mkFieldMDName str = mkName (str ++ "_md")---- | Pads constructor -mkConstrName str = mkName str-mkConstrIMDName str = mkName (str ++ "_imd")-mkfnMDName str = mkName (strToLower str ++ "_md")----- ** Naming Parsers--mkTyParserName str = mkName (strToLower str ++ "_parseM")-mkTyParserSName str = mkName (strToLower str ++ "_parseS")--mkTyParserQName str = mkName (appendLower str "_parseM")-mkTyParserSQName str = mkName (appendLower str "_parseS")--mkVarParserName str = mkName (strToLower str ++ "__p")----- ** Naming Printers--getBranchMDNameU str = mkName ((strToUpper str)++"_md")-getBranchMDNameL str = mkName ((strToLower str)++"_md")-getBranchNameU str = mkName (strToUpper str)-getBranchNameL str = mkName (strToLower str)-getStructInnerMDName name = let str = show name in mkName (str++"_imd")--mkTyPrinterName str = mkName (strToLower str ++ "_printFL")-mkTyPrinterQName str = mkName (appendLower str "_printFL")-mkTyPrinterVarName str = mkName (str ++ "__pr")- -mkTyDefName str = mkName (strToLower str ++ "_def")-mkTyDefQName str = mkName (appendLower str "_def")-mkTyDefVarName str = mkName (str ++ "__d")-- --appendTo :: QString -> String -> String-appendTo ms s = qName (init ms ++ [last ms ++ s])-appendLower ms s = qName (init ms ++ [strToLower (last ms) ++ s])--type UString = String-type LString = String--foldl1M :: Monad m => (a -> a -> m a) -> [a] -> m a-foldl1M f (x:xs) = foldM f x xs--foldr1M :: Monad m => (a -> a -> m a) -> [a] -> m a-foldr1M f [x] = return x-foldr1M f (x:xs) = f x =<< foldr1M f xs--appT2 f x y = AppT (AppT f x) y--appE3 f x y z = AppE (AppE (AppE f x) y) z-
@@ -1,983 +0,0 @@-{-# LANGUAGE TypeFamilies, GeneralizedNewtypeDeriving, TemplateHaskell, ScopedTypeVariables,- MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances,- FlexibleInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.CoreBaseTypes- Description : Core Pads base types with parsers- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.CoreBaseTypes where--import Language.Pads.Generic-import Language.Pads.MetaData-import Language.Pads.PadsParser-import Language.Pads.RegExp-import Data.Maybe--import qualified Language.Pads.Source as S-import qualified Language.Pads.Errors as E-import qualified Data.ByteString as B-import qualified Data.ByteString.Char8 as C--import Language.Pads.PadsPrinter--import Language.Haskell.TH as TH-import Language.Haskell.TH.Syntax-import Data.Data-import qualified Data.Map as M-import qualified Data.List as List-import Data.Word-import Data.Char as Char-import Data.Int-import Data.Bits--import Text.PrettyPrint.Mainland as PP-import Text.PrettyPrint.Mainland.Class--import Control.Monad---- | Metadata type for a PADS Char-type Char_md = Base_md---- | Monadic parser for a PADS Char-char_parseM :: PadsParser (Char, Base_md)-char_parseM =- handleEOF def "Char" $- handleEOR def "Char" $ do- c <- takeHeadP- returnClean c---- | Default value inserted by the parser for a PADS Char-char_def :: Char-char_def = 'X'--type instance PadsArg Char = ()-type instance Meta Char = Base_md-instance Pads1 () Char Base_md where- parsePP1 () = char_parseM- printFL1 () = char_printFL- def1 () = char_def--char_printFL :: PadsPrinter (Char, md)-char_printFL (c,bmd) = addString [c]-------------------------------------------------type CharNB = Char-type CharNB_md = Base_md--charNB_parseM :: PadsParser (CharNB, Base_md)-charNB_parseM =- handleEOF def "CharNB" $- handleEOR def "CharNB" $ do- c <- takeBitsP 8- returnClean (S.word8ToChr (fromIntegral c :: Word8))--charNB_def :: Char-charNB_def = char_def--charNB_printFL :: PadsPrinter (CharNB, md)-charNB_printFL (c, bmd) = addString [c]----------------------------------------------------------------------type BitBool = Bool-type BitBool_md = Base_md--bitBool_parseM :: PadsParser (BitBool, Base_md)-bitBool_parseM =- handleEOF False "BitBool" $- handleEOR False "BitBool" $ do- b <- takeBits8P 1- returnClean (b == 1)--bitBool_def = False--bitBool_printFL :: PadsPrinter (BitBool, md)-bitBool_printFL (bb,bbmd) = fshow bb---- type instance PadsArg Bool = ()--- type instance Meta Bool = Base_md--- instance Pads1 () Bool Base_md where--- parsePP1 () = bitBool_parseM--- printFL1 () = bitBool_printFL--- def1 () = bitBool_def---------------------------------------------------------------------type BitField = Integer-type BitField_md = Base_md--bitField_parseM :: Int -> PadsParser (BitField, Base_md)-bitField_parseM x =- if x < 0- then returnError def (E.BitWidthError 0 (fromIntegral x))- else handleEOF 0 "BitField" $- handleEOR 0 "BitField" $ do- b <- takeBitsP x- returnClean b--bitField_def :: Int -> BitField-bitField_def _ = 0--bitField_printFL :: Int -> PadsPrinter (BitField, md)-bitField_printFL _ (x, xmd) = fshow x---- type instance PadsArg Integer = ()--- type instance Meta Integer = Base_md--- instance Pads1 () Integer Base_md where--- parsePP1 () = bitField_parseM--- printFL1 () = bitField_printFL--- def1 () = bitField_def---type Bits8 = Word8-type Bits8_md = Base_md--bits8_parseM :: Int -> PadsParser (Bits8, Base_md)-bits8_parseM x =- if x < 1 || x > 8- then returnError 0 (E.BitWidthError 8 (fromIntegral x))- else handleEOF 0 "Bits8" $- handleEOR 0 "Bits8" $ do- b <- takeBits8P x- returnClean b---type Bits16 = Word16-type Bits16_md = Base_md--bits16_parseM :: Int -> PadsParser (Bits16, Base_md)-bits16_parseM x =- if x < 1 || x > 16- then returnError 0 (E.BitWidthError 16 (fromIntegral x))- else handleEOF 0 "Bits16" $- handleEOR 0 "Bits16" $ do- b <- takeBits16P x- returnClean b---type Bits32 = Word32-type Bits32_md = Base_md--bits32_parseM :: Int -> PadsParser (Bits32, Base_md)-bits32_parseM x =- if x < 1 || x > 32- then returnError 0 (E.BitWidthError 32 (fromIntegral x))- else handleEOF 0 "Bits32" $- handleEOR 0 "Bits32" $ do- b <- takeBits32P x- returnClean b---type Bits64 = Word64-type Bits64_md = Base_md--bits64_parseM :: Int -> PadsParser (Bits64, Base_md)-bits64_parseM x =- if x < 1 || x > 64- then returnError 0 (E.BitWidthError 64 (fromIntegral x))- else handleEOF 0 "Bits64" $- handleEOR 0 "Bits64" $ do- b <- takeBits64P x- returnClean b---bits8_def :: a -> Bits8-bits16_def :: a -> Bits16-bits32_def :: a -> Bits32-bits64_def :: a -> Bits64--bits8_def _ = 0-bits16_def _ = 0-bits32_def _ = 0-bits64_def _ = 0--bits8_printFL :: Int -> PadsPrinter (Bits8, md)-bits16_printFL :: Int -> PadsPrinter (Bits16, md)-bits32_printFL :: Int -> PadsPrinter (Bits32, md)-bits64_printFL :: Int -> PadsPrinter (Bits64, md)--bits8_printFL _ (x, xmd) = fshow x-bits16_printFL _ (x, xmd) = fshow x-bits32_printFL _ (x, xmd) = fshow x-bits64_printFL _ (x, xmd) = fshow x-----------------------------------------------------------------------type Int-type Int_md = Base_md---- | Monadic parser for a PADS Int-int_parseM :: PadsParser (Int,Base_md)-int_parseM =- handleEOF def "Int" $- handleEOR def "Int" $ do- c <- peekHeadP- let isNeg = (c == '-')- when isNeg (takeHeadP >> return ())- digits <- satisfy Char.isDigit- if not (null digits)- then returnClean (digitListToInt isNeg digits)- else returnError def (E.FoundWhenExpecting (mkStr c) "Int")---- | Default value inserted by the parser for a PADS Int-int_def :: Int-int_def = 0--type instance PadsArg Int = ()-type instance Meta Int = Base_md-instance Pads1 () Int Base_md where- parsePP1 () = int_parseM- printFL1 () = int_printFL- def1 () = int_def--int_printFL :: PadsPrinter (Int, Base_md)-int_printFL (i, bmd) = fshow i-----------------------------------------------------------------------type Integer-type Integer_md = Base_md---- | Monadic parser for a PADS Integer-integer_parseM :: PadsParser (Integer,Base_md)-integer_parseM =- handleEOF def "Integer" $- handleEOR def "Integer" $ do- c <- peekHeadP- let isNeg = (c == '-')- when isNeg (takeHeadP >> return ())- digits <- satisfy Char.isDigit- if not (null digits)- then returnClean (toEnum $ digitListToInt isNeg digits)- else returnError def (E.FoundWhenExpecting (mkStr c) "Integer")---- | Default value inserted by the parser for a PADS Integer-integer_def :: Integer-integer_def = 0--type instance PadsArg Integer = ()-type instance Meta Integer = Base_md-instance Pads1 () Integer Base_md where- parsePP1 () = integer_parseM- printFL1 () = integer_printFL- def1 () = integer_def--integer_printFL :: PadsPrinter (Integer, Base_md)-integer_printFL (i, bmd) = fshow i-----------------------------------------------------------------------type Float-type Float_md = Base_md---- | Monadic parser for a PADS Float, e.g. "-3.1415"-float_parseM :: PadsParser (Float,Base_md)-float_parseM =- handleEOF def "Float" $- handleEOR def "Float" $ do- -- Get leading sign- c <- peekHeadP- let isNeg = (c == '-')- when isNeg (takeHeadP >> return ())- let sign = if isNeg then "-" else ""- -- Get digits before any dot- digits1 <- satisfy Char.isDigit- -- Get optional dot- d <- peekHeadP- let hasDot = (d == '.')- when hasDot (takeHeadP >> return ())- let dec = if hasDot then "." else ""- -- Get digits after dot- digits2 <- satisfy Char.isDigit- -- Get optional exponent marker- e <- peekHeadP- let hasExp = (e == 'e')- when hasExp (takeHeadP >> return ())- let exp = if hasExp then "e" else ""- -- Get optional exponent sign- es <- peekHeadP- let hasESign = (es == '-')- when hasESign (takeHeadP >> return ())- let expSign = if hasESign then "-" else ""- -- Get digits in the exponent- digits3 <- satisfy Char.isDigit- -- As long as the double had digits- if not (null digits1)- then returnClean (read (sign ++digits1++dec++digits2++exp++expSign++digits3))- else returnError def (E.FoundWhenExpecting (mkStr c) "Float")---- | Default value inserted by the parser for a PADS Float-float_def :: Float-float_def = 0--type instance PadsArg Float = ()-type instance Meta Float = Base_md-instance Pads1 () Float Base_md where- parsePP1 () = float_parseM- printFL1 () = float_printFL- def1 () = float_def--float_printFL :: PadsPrinter (Float, Base_md)-float_printFL (d, bmd) = fshow d-----------------------------------------------------------------------type Double-type Double_md = Base_md---- | Monadic parser for a textual PADS Double, e.g. "-3.1415"-double_parseM :: PadsParser (Double,Base_md)-double_parseM =- handleEOF def "Double" $- handleEOR def "Double" $ do- -- Get leading sign- c <- peekHeadP- let isNeg = (c == '-')- when isNeg (takeHeadP >> return ())- let sign = if isNeg then "-" else ""- -- Get digits before any dot- digits1 <- satisfy Char.isDigit- -- Get optional dot- d <- peekHeadP- let hasDot = (d == '.')- when hasDot (takeHeadP >> return ())- let dec = if hasDot then "." else ""- -- Get digits after dot- digits2 <- satisfy Char.isDigit- -- Get optional exponent marker- e <- peekHeadP- let hasExp = (e == 'e')- when hasExp (takeHeadP >> return ())- let exp = if hasExp then "e" else ""- -- Get optional exponent sign- es <- peekHeadP- let hasESign = (es == '-')- when hasESign (takeHeadP >> return ())- let expSign = if hasESign then "-" else ""- -- Get digits in the exponent- digits3 <- satisfy Char.isDigit- -- As long as the double had digits- if not (null digits1)- then returnClean (read (sign ++digits1++dec++digits2++exp++expSign++digits3))- else returnError def (E.FoundWhenExpecting (mkStr c) "Double")---- | Default value inserted by the parser for a PADS Float-double_def :: Double-double_def = 0--type instance PadsArg Double = ()-type instance Meta Double = Base_md-instance Pads1 () Double Base_md where- parsePP1 () = double_parseM- printFL1 () = double_printFL- def1 () = 0--double_printFL :: PadsPrinter (Double, Base_md)-double_printFL (d, bmd) = fshow d------------------------------------------------------------------------- tries to parse @a@ without consuming the input string-type Try a = a-type Try_md a_md = (Base_md, a_md)--try_parseM :: PadsMD md => PadsParser (rep,md) -> PadsParser (Try rep, Try_md md)-try_parseM p = do- (rep,md) <- parseTry p- return (rep, (cleanBasePD, md))--try_printFL :: PadsPrinter (a,a_md) -> PadsPrinter (Try a,Try_md a_md)-try_printFL p _ = printNothing--try_def :: a -> Try a-try_def d = d----------------------------------------------------------------------type Digit = Int-type Digit_md = Base_md---- | Monadic parser for a PADS Digit according to @'isDigit'@-digit_parseM :: PadsParser (Digit, Base_md)-digit_parseM =- handleEOF def "Pdigit" $- handleEOR def "Pdigit" $ do- c <- takeHeadP- if isDigit c- then returnClean (digitToInt c)- else returnError def (E.FoundWhenExpecting [c] "Digit")---- | Default value inserted by the parser for a PADS Digit-digit_def :: Digit-digit_def = 0--digit_printFL :: PadsPrinter (Digit, Base_md)-digit_printFL (i, bmd) = fshow i------------------------------------------------------------------------type String-type String_md = Base_md--string_parseM :: PadsParser (String, Base_md)-string_parseM = do- document <- getAllBinP- returnClean $ C.unpack document---- | Default value inserted by the parser for a PADS String-string_def = ""--type instance PadsArg String = ()-type instance Meta String = Base_md-instance Pads1 () String Base_md where- parsePP1 () = string_parseM- printFL1 () = string_printFL- def1 () = string_def--string_printFL :: PadsPrinter (String, Base_md)-string_printFL (str, bmd) = addString str---------------------------------------------------------------------type StringNB = String-type StringNB_md = Base_md--stringNB_parseM :: PadsParser (String, Base_md)-stringNB_parseM = do- str <- drainSourceNBP- returnClean str--stringNB_def = string_def--stringNB_printFL :: PadsPrinter (String, Base_md)-stringNB_printFL = string_printFL---------------------------------------------------------------------newtype Text = Text S.RawStream- deriving (Eq, Show, Data, Typeable, Ord)-type Text_md = Base_md--text_parseM :: PadsParser (Text, Base_md)-text_parseM = do- document <- getAllBinP- returnClean (Text document)--instance Pretty Text where- ppr (Text str) = text "ASCII"--text_def :: Text-text_def = Text $ B.pack []--type instance PadsArg Text = ()-type instance Meta Text = Base_md-instance Pads1 () Text Base_md where- parsePP1 () = text_parseM- printFL1 () = text_printFL- def1 () = text_def--text_printFL :: PadsPrinter (Text, Base_md)-text_printFL (Text str, bmd) = addBString str----------------------------------------------------------------------newtype Binary = Binary S.RawStream- deriving (Eq, Show, Data, Typeable, Ord)-type Binary_md = Base_md--binary_parseM :: PadsParser (Binary, Base_md)-binary_parseM = do- document <- getAllBinP- returnClean (Binary document)--instance Pretty Binary where- ppr (Binary str) = text "Binary"--binary_def :: Binary-binary_def = Binary $ B.pack []--type instance PadsArg Binary = ()-type instance Meta Binary = Base_md-instance Pads1 () Binary Base_md where- parsePP1 () = binary_parseM- printFL1 () = binary_printFL- def1 () = binary_def--binary_printFL :: PadsPrinter (Binary, Base_md)-binary_printFL (Binary bstr, bmd) = addBString bstr------------------------------------------------------------------------ | string with end character. Ex:------ > StringC ','-type StringC = String-type StringC_md = Base_md--stringC_parseM :: Char -> PadsParser (StringC, Base_md)-stringC_parseM c =- handleEOF (stringC_def c) "StringC" $- handleEOR (stringC_def c) "StringC" $ do- str <- satisfy (\c'-> c /= c')- returnClean str--stringC_def c = ""--stringC_printFL :: Char -> PadsPrinter (StringC, Base_md)-stringC_printFL c (str, bmd) = addString str---------------------------------------------------------------------type StringCNB = String-type StringCNB_md = Base_md--stringCNB_parseM :: Char -> PadsParser (StringCNB, Base_md)-stringCNB_parseM c =- handleEOF (stringCNB_def c) "StringCNB" $- handleEOR (stringCNB_def c) "StringCNB" $ do- str <- satisfyNBP (\c' -> c /= c')- returnClean str--stringCNB_def :: Char -> StringCNB-stringCNB_def = stringC_def--stringCNB_printFL :: Char -> PadsPrinter (StringCNB, Base_md)-stringCNB_printFL = stringC_printFL----------------------------------------------------------------------- | string of fixed length-type StringFW = String-type StringFW_md = Base_md--stringFW_parseM :: Int -> PadsParser (StringFW, Base_md)-stringFW_parseM 0 = returnClean ""-stringFW_parseM n =- handleEOF (stringFW_def n) "StringFW" $- handleEOR (stringFW_def n) "StringFW" $ do- str <- takeP n- if (length str) == n- then returnClean str- else returnError (stringFW_def n) (E.Insufficient (length str) n)--stringFW_def :: Int -> StringFW-stringFW_def n = replicate n 'X'--stringFW_printFL :: Int -> PadsPrinter (StringFW, Base_md)-stringFW_printFL n (str, bmd) = addString (take n str)---------------------------------------------------------------------type StringFWNB = String-type StringFWNB_md = Base_md--stringFWNB_parseM :: Int -> PadsParser (StringFW, Base_md)-stringFWNB_parseM 0 = returnClean ""-stringFWNB_parseM n =- handleEOF (stringFWNB_def n) "StringFWNB" $- handleEOR (stringFWNB_def n) "StringFWNB" $ do- str <- takeBytesNBP n- let str' = map S.word8ToChr (B.unpack str)- if (length str') == n- then returnClean str'- else returnError (stringFWNB_def n) (E.Insufficient (length str') n)--stringFWNB_def :: Int -> StringFW-stringFWNB_def n = replicate n 'X'--stringFWNB_printFL :: Int -> PadsPrinter (StringFW, Base_md)-stringFWNB_printFL = stringFW_printFL----------------------------------------------------------------------- | string of variable length-type StringVW = String-type StringVW_md = Base_md--stringVW_parseM :: Int -> PadsParser (StringVW, Base_md)-stringVW_parseM 0 = returnClean ""-stringVW_parseM n =- handleEOF (stringVW_def n) "StringVW" $- handleEOR (stringVW_def n) "StringVW" $ do- str <- takeP n- returnClean str--stringVW_def :: Int -> StringVW-stringVW_def n = replicate n 'X'--stringVW_printFL :: Int -> PadsPrinter (StringVW, Base_md)-stringVW_printFL n (str, bmd) = addString (take n str)------ string of variable length (end if EOR)---type StringVW = String---type StringVW_md = Base_md------stringVW_parseM :: (Bool,Int) -> PadsParser (StringVW, Base_md)---stringVW_parseM (endIfEOR,0) = returnClean ""---stringVW_parseM (endIfEOR,n) = do--- let (doEOF, doEOR) = if endIfEOR then (checkEOF, checkEOR) else (handleEOF, handleEOR)--- doEOF "" "StringVW" $ doEOR "" "StringVW" $ do--- c1 <- takeHeadP--- (rest, rest_md) <- stringVW_parseM (endIfEOR,pred n)--- return (c1:rest, rest_md)------stringVW_def (endIfEOR,n) = replicate n 'X'------stringVW_printFL :: (Bool,Int) -> PadsPrinter (StringVW, Base_md)---stringVW_printFL (endIfEOR,n) (str, bmd) = addString (take n str)------------------------------------------------------------------------------------------------------------------------------------------ | string with matching expression. For example:------ > [pads| type StrME = StringME 'a+' |]-type StringME = String-type StringME_md = Base_md--stringME_parseM :: RE -> PadsParser (StringME, Base_md)-stringME_parseM re =- handleEOF (stringME_def re) "StringME" $ do- match <- regexMatchP re- case match of- Just str -> returnClean str- Nothing -> returnError (stringME_def re) (E.RegexMatchFail (show re))--stringME_def (RE re) = "" -- should invert the re-stringME_def (REd re d) = d--stringME_printFL :: RE -> PadsPrinter (StringME, Base_md)-stringME_printFL re (str, bmd) = addString str- -- We're not likely to check that str matches re----------------------------------------------------------------------- | string matching given native regex. PADS uses posix regex (from the--- regex-posix package). For example:------ > [pads| StringSE <| RE "b|c" |>|]-type StringSE = String-type StringSE_md = Base_md--stringSE_parseM :: RE -> PadsParser (StringSE, Base_md)-stringSE_parseM re =- checkEOF (stringSE_def re) "StringSE" $- checkEOR (stringSE_def re) "StringSE" $ do- match <- regexStopP re- case match of- Just str -> returnClean str- Nothing -> returnError (stringSE_def re) (E.RegexMatchFail (show re))--stringSE_def (RE re) = "" -- should invert the re-stringSE_def (REd re d) = d--stringSE_printFL :: RE -> PadsPrinter (StringSE, Base_md)-stringSE_printFL re (str, bmd) = addString str------------------------------------------------------------------------ | string with a predicate. For example:------ > [pads| type Digits = StringP Char.isDigit |]-type StringP = String-type StringP_md = Base_md--stringP_parseM :: (Char -> Bool) -> PadsParser (StringP, Base_md)-stringP_parseM p =- handleEOF (stringP_def p) "StringP" $- handleEOR (stringP_def p) "StringP" $ do- str <- satisfy p- returnClean str--stringP_def _ = ""--stringP_printFL :: (Char -> Bool) -> PadsPrinter (StringP, Base_md)-stringP_printFL p (str, bmd) = addString str----------------------------------------------------------------------- | string predicate with escape condition-type StringPESC = String-type StringPESC_md = Base_md--stringPESC_parseM :: (Bool, (Char, [Char])) -> PadsParser(StringPESC, Base_md)-stringPESC_parseM arg @ (endIfEOR, (escape, stops)) =- let (doEOF, doEOR) = if endIfEOR then (checkEOF, checkEOR) else (handleEOF, handleEOR)- in- doEOF "" "StringPESC" $- doEOR "" "StringPESC" $ do- { c1 <- peekHeadP- ; if c1 `elem` stops then- returnClean ""- else if c1 == escape then do- { takeHeadP- ; doEOF [c1] "StringPESC" $- doEOR [c1] "StringPESC" $ do- { c2 <- takeHeadP- ; if (c2 == escape) || (c2 `elem` stops) then do- { (rest, rest_md) <- stringPESC_parseM arg- ; return (c2:rest, rest_md)- }- else do- { (rest, rest_md) <- stringPESC_parseM arg- ; return (c1:c2:rest, rest_md)- }- }- } else do- { c1 <- takeHeadP- ; (rest, rest_md) <- stringPESC_parseM arg- ; return (c1:rest, rest_md)- }- }--stringPESC_def :: (Bool, (Char, [Char])) -> String-stringPESC_def arg@(endIfEOR, (escape, stops)) = ""--stringPESC_printFL :: (Bool, (Char, [Char])) -> PadsPrinter (StringPESC, Base_md)-stringPESC_printFL (_, (escape, stops)) (str, bmd) =- let replace c = if c `elem` stops then escape : [c] else [c]- newStr = concat (map replace str)- in addString newStr------------------------------------------------------------------------class LitParse a where- litParse :: a -> PadsParser ((), Base_md)- litPrint :: a -> FList--strLit_parseM :: String -> PadsParser ((), Base_md)-strLit_parseM s =- handleEOF () s $- handleEOR () s $ do- match <- scanStrP s- case match of- Just [] -> returnClean ()- Just junk -> returnError () (E.ExtraBeforeLiteral s)- Nothing -> returnError () (E.MissingLiteral s)--strLit_printFL :: String -> FList-strLit_printFL str = addString str--instance LitParse Char where- litParse = charLit_parseM- litPrint = charLit_printFL--charLit_parseM :: Char -> PadsParser ((),Base_md)-charLit_parseM c =- handleEOF () (mkStr c) $- handleEOR () (mkStr c) $ do- c' <- takeHeadP- if c == c' then returnClean () else do- foundIt <- scanP c- returnError () (if foundIt- then E.ExtraBeforeLiteral (mkStr c)- else E.MissingLiteral (mkStr c))--charLit_printFL :: Char -> FList-charLit_printFL c = addString [c]--instance LitParse String where- litParse = strLit_parseM- litPrint = strLit_printFL---instance LitParse RE where- litParse = reLit_parseM- litPrint = reLit_printFL--reLit_parseM :: RE -> PadsParser ((), Base_md)-reLit_parseM re = do- (match, md) <- stringME_parseM re- if numErrors md == 0- then return ((), md)- else badReturn ((), md)--reLit_printFL :: RE -> FList-reLit_printFL (RE re) = addString "--REGEXP LITERAL-- "-reLit_printFL (REd re def) = addString def---- | End of File-type EOF = ()-type EOF_md = Base_md--eof_parseM :: PadsParser (EOF, Base_md)-eof_parseM = do- isEof <- isEOFP- if isEof then returnClean ()- else returnError () (E.ExtraBeforeLiteral "Eof")---- | End of Record-type EOR = ()-type EOR_md = Base_md--eor_parseM :: PadsParser (EOR, Base_md)-eor_parseM =- handleEOF () "EOR" $ do- isEor <- isEORP- if isEor then doLineEnd- else returnError () (E.LineError "Expecting EOR")--eor_printFL :: (EOR,Base_md) -> FList-eor_printFL = const eorLit_printFL--eOR_printFL = eor_printFL--eOR_def :: EOR-eOR_def = ()--eof_printFL :: (EOF,Base_md) -> FList-eof_printFL = const eofLit_printFL--eOF_printFL = eof_printFL--eOF_def :: EOF-eOF_def = ()--eorLit_printFL :: FList-eorLit_printFL = printEOR--eofLit_printFL :: FList-eofLit_printFL = printEOF---------------------------------------------------------------------newtype Void = Void ()- deriving (Eq, Show, Data, Typeable, Ord)-type Void_md = Base_md--void_parseM :: PadsParser (Void, Base_md)-void_parseM = returnClean (Void ())--void_def :: Void-void_def = Void ()--type instance Meta Void = Base_md-instance Pads1 () Void Base_md where- parsePP1 () = void_parseM- printFL1 () = void_printFL- def1 () = void_def--void_printFL :: PadsPrinter (Void,Base_md)-void_printFL v = nil----pstrLit_printQ :: String -> FList-pstrLit_printQ str = addString str--tuple_printQ :: (String, String, String) -> FList-tuple_printQ (s1,s2,s3) = pstrLit_printQ s1 +++ pstrLit_printQ s2 +++ pstrLit_printQ s3--rtuple_printQ :: (String, String, String) -> FList-rtuple_printQ ss = tuple_printQ ss +++ (addString ['\n'])--list_printQ :: [(String,String,String)] -> FList-list_printQ [] = nil-list_printQ (item:items) = rtuple_printQ item +++ list_printQ items---------------------------------------------handleEOF val str p- = do { isEof <- isEOFP- ; if isEof then- returnError val (E.FoundWhenExpecting "EOF" str)- else p}--handleEOR val str p- = do { isEor <- isEORP- ; if isEor then- returnError val (E.FoundWhenExpecting "EOR" str)- else p}--checkEOF val str p- = do { isEof <- isEOFP- ; if isEof then- returnClean val- else p}--checkEOR val str p- = do { isEor <- isEORP- ; if isEor then- returnClean val- else p}--------------------------------------- BINARY TYPES ----------------------------------------type Bytes = S.RawStream-type Bytes_md = Base_md--bytes_parseM :: Int -> PadsParser (Bytes,Bytes_md)-bytes_parseM n =- handleEOF (def1 n) "Bytes" $- handleEOR (def1 n) "Bytes" $ do- bytes <- takeBytesP n- if B.length bytes == n- then returnClean bytes- else returnError (def1 n) (E.Insufficient (B.length bytes) n)--bytes_printFL :: Int -> PadsPrinter (Bytes, Bytes_md)-bytes_printFL n (bs, bmd) =- addBString bs--bytes_def :: Int -> Bytes-bytes_def i = B.pack $ replicate i (0::Word8)--type instance PadsArg Bytes = Int-type instance Meta Bytes = Bytes_md-instance Pads1 Int Bytes Bytes_md where- parsePP1 = bytes_parseM- printFL1 = bytes_printFL- def1 i = bytes_def i---type BytesNB = S.RawStream-type BytesNB_md = Base_md--bytesNB_parseM :: Int -> PadsParser (BytesNB, BytesNB_md)-bytesNB_parseM n =- handleEOF (def1 n) "BytesNB" $- handleEOR (def1 n) "BytesNB" $ do- bytes <- takeBytesNBP n- if B.length bytes == n- then returnClean bytes- else returnError (def1 n) (E.Insufficient (B.length bytes) n)--bytesNB_printFL :: Int -> PadsPrinter (BytesNB, BytesNB_md)-bytesNB_printFL = bytes_printFL--bytesNB_def :: Int -> BytesNB-bytesNB_def = bytes_def--{- Helper functions -}-mkStr c = "'" ++ [c] ++ "'"
@@ -1,77 +0,0 @@-{-# LANGUAGE NamedFieldPuns, DeriveDataTypeable #-}-{-# OPTIONS_HADDOCK prune #-} -{-|- Module : Language.Pads.Errors- Description : Parse error reporting support- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental--}--module Language.Pads.Errors where-import Text.PrettyPrint.Mainland as PP-import Text.PrettyPrint.Mainland.Class-import qualified Language.Pads.Source as S-import Data.Data---- | Errors which can be encountered at runtime when parsing a Pads type-data ErrMsg =- FoundWhenExpecting String String- | MissingLiteral String- | ExtraBeforeLiteral String- | LineError String- | Insufficient Int Int- | RegexMatchFail String- | TransformToDstFail String String String- | TransformToSrcFail String String String- | UnderlyingTypedefFail- | PredicateFailure- | ExtraStuffBeforeTy String String- | FileError String String- | BitWidthError Int Int- deriving (Typeable, Data, Eq, Ord, Show)--{- XXX-KSF: fix pretty printing to use pretty printing combinators rather than string ++ -}--- | Pretty printer for Pads runtime error messages.-instance Pretty ErrMsg where- ppr (FoundWhenExpecting str1 str2) = text ("Encountered " ++ str1 ++ " when expecting " ++ str2 ++ ".")- ppr (MissingLiteral s) = text ("Missing Literal: " ++ s ++ ".")- ppr (ExtraBeforeLiteral s) = text ("Extra bytes before literal: " ++ s ++ ".")- ppr (ExtraStuffBeforeTy junk ty) = text ("Extra bytes: " ++ junk ++ " before " ++ ty ++ ".")- ppr (Insufficient found expected) = text("Found " ++ show found ++ " bytes when looking for " ++ show expected ++ "bytes.")- ppr (RegexMatchFail s) = text ("Failed to match regular expression: " ++ s ++ ".")- ppr (TransformToDstFail s1 s2 s3) = text ("Parsing transform " ++ s1 ++ " failed on input: " ++ s2 ++ s3)- ppr (TransformToSrcFail s1 s2 s3) = text ("Printing transform "++ s1 ++ " failed on input: " ++ s2 ++ s3)- ppr (LineError s) = text s- ppr UnderlyingTypedefFail = text "Pads predicate is true, but underlying type had an error."- ppr PredicateFailure = text "Pads predicate is false."- ppr (FileError err file) = text ("Problem with file: " ++ file ++ "("++ err ++ ").")- ppr (BitWidthError x y) = text ("Bad field width: " ++ show y ++ " cannot fit in " ++ show x ++ ".")---- | Error information relating back to the source input-data ErrInfo = ErrInfo { msg :: ErrMsg,- position :: Maybe S.Span }- deriving (Typeable, Data, Eq, Ord, Show)---- | Pretty printer for reporting where in the source text a parse error--- occured.-instance Pretty ErrInfo where- ppr ErrInfo{msg,position} = ppr msg <+>- case position of- Nothing -> empty- Just pos -> text "at:" <+> ppr pos---- | Always just pick the first error message-mergeErrInfo ErrInfo{msg=msg1, position=position1} ErrInfo{msg=msg2, position=position2} =- ErrInfo{msg=msg1, position=position1}---- | Merge errors in the Maybe monad-maybeMergeErrInfo m1 m2 = case (m1,m2) of- (Nothing,Nothing) -> Nothing- (Just p, Nothing) -> Just p- (Nothing, Just p) -> Just p- (Just p1, Just p2) -> Just (mergeErrInfo p1 p2)-
@@ -1,267 +0,0 @@-{-# LANGUAGE TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses- , FlexibleInstances, DeriveDataTypeable, NamedFieldPuns, ScopedTypeVariables #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.GenPretty- Description : Template haskell based pretty printing instances- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.GenPretty where--import Language.Pads.Padsc-import Language.Pads.Errors-import Language.Pads.MetaData-import Language.Pads.TH--import Language.Haskell.TH as TH hiding (ppr)--import Text.PrettyPrint.Mainland-import Text.PrettyPrint.Mainland.Class--import qualified Data.List as L-import qualified Data.Set as S-import Control.Monad--import System.Posix.Types-import Data.Word-import Data.Int-import Data.Time-import Debug.Trace as D--pprE argE = AppE (VarE 'ppr) argE-pprListEs argEs = ListE (map pprE argEs)-pprCon1E argE = AppE (VarE 'pprCon1) argE-pprCon2E argE = AppE (VarE 'pprCon2) argE--pprCon1 arg = ppr (toList1 arg)-pprCon2 arg = ppr (toList2 arg)---- | Get all the names of types referenced within the given 'TH.Type'-getTyNames :: TH.Type -> S.Set TH.Name-getTyNames ty = case ty of- ForallT tvb cxt ty' -> getTyNames ty'- VarT name -> S.empty- ConT name -> S.singleton name- TupleT i -> S.empty- ArrowT -> S.empty- ListT -> S.empty- AppT t1 t2 -> getTyNames t1 `S.union` getTyNames t2- SigT ty kind -> getTyNames ty---- | Get all the types referenced within the given Haskell constructor.-getTyNamesFromCon :: TH.Con -> S.Set TH.Name-getTyNamesFromCon con = case con of- (NormalC name stys) -> S.unions (map (\(_,ty) -> getTyNames ty) stys)- (RecC name vstys) -> S.unions (map (\(_,_,ty) -> getTyNames ty) vstys)- (InfixC st1 name st2) -> getTyNames (snd st1) `S.union` getTyNames (snd st2)- (ForallC tvb cxt con) -> getTyNamesFromCon con---- | Recursively reify types to get all the named types referenced by the given--- name-getNamedTys :: TH.Name -> Q [TH.Name]-getNamedTys ty_name = S.toList <$> getNamedTys' S.empty (S.singleton ty_name)---- | Helper for 'getNamedTys'-getNamedTys' :: S.Set TH.Name -> S.Set TH.Name -> Q (S.Set TH.Name)-getNamedTys' answers worklist =- if S.null worklist then return answers- else do- { let (ty_name, worklist') = S.deleteFindMin worklist- ; let answers' = S.insert ty_name answers- ; info <- reify ty_name- ; case info of- TyConI (NewtypeD [] ty_name' [] _ con derives) -> do- { let all_nested = getTyNamesFromCon con- ; let new_nested = all_nested `S.difference` answers'- ; let new_worklist = worklist' `S.union` new_nested- ; getNamedTys' answers' new_worklist- }- TyConI (DataD [] ty_name' [] _ cons derives) -> do- { let all_nested = S.unions (map getTyNamesFromCon cons)- ; let new_nested = all_nested `S.difference` answers'- ; let new_worklist = worklist' `S.union` new_nested- ; getNamedTys' answers' new_worklist- }- TyConI (TySynD _ _ _ ) -> do {reportError ("getTyNames: unimplemented TySynD case " ++ (nameBase ty_name)); return answers'}- TyConI (ForeignD _) -> do {reportError ("getTyNames: unimplemented ForeignD case " ++ (nameBase ty_name)); return answers'}- PrimTyConI _ _ _ -> return answers- otherwise -> do {reportError ("getTyNames: pattern didn't match for " ++ (nameBase ty_name)); return answers'}- }---- | All the base types supported by Pads-baseTypeNames = S.fromList [ ''Int, ''Char, ''Digit, ''Text, ''String, ''StringFW, ''StringME- , ''StringSE, ''COff, ''EpochTime, ''FileMode, ''Int, ''Word, ''Int64- , ''Language.Pads.Errors.ErrInfo, ''Bool, ''Binary, ''Base_md, ''UTCTime, ''TimeZone- ]---- | Recursively make the pretty printing instance for a given named type by--- also making instances for all nested types.-mkPrettyInstance :: TH.Name -> Q [TH.Dec]-mkPrettyInstance ty_name = mkPrettyInstance' (S.singleton ty_name) baseTypeNames []--mkMe :: TH.Name -> Q [TH.Dec]-mkMe n = do- D.traceM "HELLOOOOOOOOOO"- return []---- | Helper for 'mkPrettyInstance'-mkPrettyInstance' :: S.Set TH.Name -> S.Set TH.Name -> [TH.Dec] -> Q [TH.Dec]-mkPrettyInstance' worklist done decls =- if S.null worklist then return decls- else do- let (ty_name, worklist') = S.deleteFindMin worklist- if ty_name `S.member` done then mkPrettyInstance' worklist' done decls- else do- let tyBaseName = nameBase ty_name- let baseStr = strToLower tyBaseName- let specificPprName = mkName (baseStr ++ "_ppr")- let funName = mkName (strToLower (tyBaseName ++ "_ppr"))- let inst = AppT (ConT ''Pretty) (ConT ty_name)- let genericPprName = mkName "ppr"- let ppr_method = ValD (VarP genericPprName) (NormalB (VarE specificPprName)) []- let instD = InstanceD Nothing [] inst [ppr_method]- let newDone = S.insert ty_name done- info <- reify ty_name- (nestedTyNames, decls') <- case info of- TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT ListT ty)]) derives) -> do -- List- { let nestedTyNames = getTyNames ty--- ; reportError ("list case " ++ (nameBase ty_name))- ; (itemsE,itemsP) <- doGenPE "list"- ; let mapE = AppE (AppE (VarE 'map) (VarE 'ppr)) itemsE- ; let bodyE = AppE (AppE (VarE 'namedlist_ppr) (nameToStrLit ty_name)) mapE- ; let argP = ConP (mkName tyBaseName) [itemsP]- ; let clause = Clause [argP] (NormalB bodyE) []- ; return (nestedTyNames, [instD, FunD specificPprName [clause]])- }- TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT (AppT (ConT ty_con_name) ty_arg1) ty_arg2) ]) derives) -> do -- curry rep (Map)- { let nestedTyNames = getTyNames ty_arg2- ; (argP, body) <- mkPatBody tyBaseName pprCon2E--- ; reportError ("curry rep case " ++ (nameBase ty_name))- ; let clause = Clause [argP] body []- ; return (nestedTyNames, [instD, FunD specificPprName [clause]])- }- TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT (ConT ty_con_name) ty_arg) ]) derives) -> do -- con rep (Set)- { let nestedTyNames = getTyNames ty_arg- ; (argP, body) <- mkPatBody tyBaseName pprCon1E--- ; reportError ("con rep case " ++ (nameBase ty_name))- ; let clause = Clause [argP] body []- ; return (nestedTyNames, [instD, FunD specificPprName [clause]])- }- TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, ConT core_name)]) derives) -> do -- App, Typedef- { (argP, body) <- mkPatBody tyBaseName pprE--- ; reportError ("app, typedef case " ++ (nameBase ty_name))- ; let clause = Clause [argP] body []- ; return (S.singleton core_name, [instD, FunD specificPprName [clause]])- }- TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, ty)]) derives) | isTuple ty -> do -- Tuple- { let nestedTyNames = getTyNames ty--- ; reportError ("tuple case " ++ (nameBase ty_name))- ; let (len, tys) = tupleTyToListofTys ty- ; (exps, pats) <- doGenPEs len "tuple"- ; let bodyE = AppE (AppE (VarE 'namedtuple_ppr) (LitE (StringL tyBaseName))) (pprListEs exps)- ; let argP = ConP (mkName tyBaseName) [TupP pats]- ; let clause = Clause [argP] (NormalB bodyE) []- ; return (nestedTyNames, [instD, FunD specificPprName [clause]])- }- TyConI (DataD [] ty_name' [] _ cons derives) | isDataType cons -> do- { let nestedTyNames = S.unions (map getTyNamesFromCon cons)- ; (exp, pat) <- doGenPE "case_arg"- ; matches <- mapM mkClause cons- ; let caseE = CaseE exp matches- ; let clause = Clause [pat] (NormalB caseE) []- ; return (nestedTyNames, [instD, FunD specificPprName [clause]] )- }- TyConI (DataD [] ty_name' [] _ cons derives) | isRecordType cons -> do- { let nestedTyNames = S.unions (map getTyNamesFromCon cons)--- ; report (length cons /= 1) ("GenPretty: record " ++ (nameBase ty_name') ++ " did not have a single constructor.")- ; clause <- mkRecord (L.head cons)- ; return (nestedTyNames, [instD, FunD specificPprName [clause]])- }- TyConI (DataD _ ty_name' _ _ cons derives) -> do- {--- reportError ("DataD pattern didn't match for"++(nameBase ty_name))- ; return (S.empty, [])}- TyConI (TySynD ty_name' [] ty) -> do- { let nestedTyNames = getTyNames ty--- ; reportError ("tysyn for"++(nameBase ty_name))- ; return (nestedTyNames, [])}- TyConI (TySynD ty_name' tyVarBndrs ty) -> do- { let nestedTyNames = getTyNames ty--- ; reportError ("tysyn for"++(nameBase ty_name))- ; return (nestedTyNames, [])}- TyConI dec -> do {reportError ("otherwise; tyconI case "++(nameBase ty_name)) ; return (S.empty, [])}- otherwise -> do {reportError ("pattern didn't match for "++(nameBase ty_name)) ; return (S.empty, [])}- let newWorklist = worklist `S.union` nestedTyNames- let newDecls = decls'++decls- mkPrettyInstance' newWorklist newDone newDecls---- | Is the given type a TupleT?-isTuple (TupleT n) = True-isTuple (AppT ty _) = isTuple ty---- | Is the given constructor a normal Haskell constructor?-isDataType [] = False-isDataType (NormalC _ _ : rest) = True-isDataType _ = False---- | Is the given constructor a Haskell record constructor?-isRecordType [] = False-isRecordType (RecC _ _ : rest) = True-isRecordType _ = False---- | Make the pattern body of a pretty printer expression for a named Pads type-mkPatBody core_name_str pprE = do- (exp,pat) <- doGenPE "arg"- bodyE <- [| namedty_ppr $(litE $ stringL core_name_str) $(return $ pprE exp) |]- argP <- conP (mkName core_name_str) [return pat]- return (argP, NormalB bodyE)---- | Make the pattern body of a pretty printer expression for a Pads type /--- data constructor without arguments.-mkPatBodyNoArg core_name_str = do- bodyE <- [| text $(litE $ stringL core_name_str) |]- argP <- conP (mkName core_name_str) []- return (argP, NormalB bodyE)---- | Make the clause for the data constructor of a data type based on whether or--- not it has any arguments.-mkClause con = case con of- NormalC name [] -> do- { (argP, body) <- mkPatBodyNoArg (nameBase name)- ; return (Match argP body [])- }- NormalC name ty_args -> do- { (argP, body) <- mkPatBody (nameBase name) pprE- ; return (Match argP body [])- }- otherwise -> error "mkClause not implemented for this kind of constructor."---- | Make the Haskell clause for a Pads record.-mkRecord (RecC rec_name fields) = do- fieldInfo <- mapM mkField fields- let (recPs, recEs) = unzip fieldInfo- let recP = RecP rec_name recPs- let bodyE = AppE (AppE (VarE 'record_ppr) (nameToStrLit rec_name)) (ListE recEs)- return (Clause [recP] (NormalB bodyE) [])---- | Make the field pretty printer case.-mkField (field_name, _, ty) = do- (expE, pat) <- doGenPE (nameBase field_name)- fieldE <- [| field_ppr $(return $ nameToStrLit field_name) $(return $ pprE expE) |]- return ((field_name, pat), fieldE)--nameToStrLit name = LitE (StringL (nameBase name))--instance Pretty a => Pretty (PMaybe a) where- ppr PNothing = text ""- ppr (PJust a) = ppr a--instance Pretty a => Pretty (PMaybe_imd a) where- ppr (PNothing_imd _) = text ""- ppr (PJust_imd a) = ppr a
@@ -1,203 +0,0 @@-{-# LANGUAGE TypeFamilies, ConstraintKinds, MultiParamTypeClasses- , FunctionalDependencies, ScopedTypeVariables, FlexibleContexts- , Rank2Types, FlexibleInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Generic- Description : Default parse values using GHC Generics- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Generic where--import Language.Pads.MetaData-import Language.Pads.PadsParser-import qualified Language.Pads.Errors as E-import qualified Language.Pads.Source as S-import Language.Pads.PadsPrinter-import qualified Data.ByteString as B-import qualified Control.Exception as CE-import Data.Data-import Data.Generics.Aliases (extB, ext1B)-import Data.Map (Map(..))-import qualified Data.Map as Map-import Data.Set (Set(..))-import qualified Data.Set as Set-import Language.Pads.Errors--import System.Posix.Types-import Foreign.C.Types-import System.CPUTime--type Pads rep md = Pads1 () rep md--def :: Pads rep md => rep-def = def1 ()-defaultMd :: Pads rep md => rep -> md-defaultMd = defaultMd1 ()-parsePP :: Pads rep md => PadsParser (rep,md)-parsePP = parsePP1 ()-printFL :: Pads rep md => PadsPrinter (rep,md)-printFL = printFL1 ()-defaultRepMd :: Pads rep md => (rep,md)-defaultRepMd = defaultRepMd1 ()--parseRep :: Pads rep md => String -> rep-parseRep cs = fst $ fst $ parseStringInput parsePP cs--parseS :: Pads rep md => String -> ((rep, md), String)-parseS cs = parseStringInput parsePP cs--parseBS :: Pads rep md => B.ByteString -> ((rep, md), B.ByteString)-parseBS cs = parseByteStringInput parsePP cs--parseFile :: Pads rep md => FilePath -> IO (rep, md)-parseFile file = parseFileWith parsePP file--parseFileWithDisc :: Pads rep md => S.RecordDiscipline -> FilePath -> IO (rep, md)-parseFileWithDisc d file = parseFileWithD d parsePP file--printS :: Pads rep md => (rep,md) -> (String)-printS = S.byteStringToStr . printBS--printRep :: Pads rep md => rep -> String-printRep = printRep1 ()--printBS :: Pads rep md => (rep,md) -> (B.ByteString)-printBS r = let f = (printFL r) in f B.empty--printFile :: Pads rep md => FilePath -> (rep,md) -> IO ()-printFile filepath r = do- let str = printBS r- B.writeFile filepath str--printFileRep :: Pads rep md => FilePath -> rep -> IO ()-printFileRep filepath r = printFile filepath (r,defaultMd r)--type family PadsArg rep :: *--class (Data rep, PadsMD md, PadsMD (Meta rep)) => Pads1 arg rep md | rep -> md, rep -> arg where- def1 :: arg -> rep- def1 = \_ -> gdef- defaultMd1 :: arg -> rep -> md- defaultMd1 _ _ = myempty- parsePP1 :: arg -> PadsParser (rep,md)- printFL1 :: arg -> PadsPrinter (rep,md)- defaultRepMd1 :: arg -> (rep,md)- defaultRepMd1 arg = (rep,md) where- rep = def1 arg- md = defaultMd1 arg rep--parseRep1 :: Pads1 arg rep md => arg -> String -> rep-parseRep1 arg cs = fst $ fst $ parseStringInput (parsePP1 arg) cs--parseS1 :: Pads1 arg rep md => arg -> String -> ((rep, md), String)-parseS1 arg cs = parseStringInput (parsePP1 arg) cs--parseBS1 :: Pads1 arg rep md => arg -> B.ByteString -> ((rep, md), B.ByteString)-parseBS1 arg cs = parseByteStringInput (parsePP1 arg) cs---parseString1 :: Pads1 arg rep md => arg-> String -> (rep, md)-parseString1 arg str = parseStringWith (parsePP1 arg) str--parseFile1 :: Pads1 arg rep md => arg-> FilePath -> IO (rep, md)-parseFile1 arg file = parseFileWith (parsePP1 arg) file--parseFile1WithDisc :: Pads1 arg rep md => S.RecordDiscipline -> arg -> FilePath -> IO (rep, md)-parseFile1WithDisc d arg file = parseFileWithD d (parsePP1 arg) file--printS1 :: Pads1 arg rep md => arg -> (rep,md) -> (String)-printS1 arg (rep,md) = S.byteStringToStr (printBS1 arg (rep,md))--printRep1 :: Pads1 arg rep md => arg -> rep -> String-printRep1 arg rep = printS1 arg (rep,defaultMd1 arg rep)--printBS1 :: Pads1 arg rep md => arg -> (rep,md) -> (B.ByteString)-printBS1 arg r = let f = (printFL1 arg r) in f B.empty-printFile1 :: Pads1 arg rep md => arg -> FilePath -> (rep,md) -> IO ()-printFile1 arg filepath r = do- let str = printBS1 arg r- B.writeFile filepath str--printFileRep1 :: Pads1 arg rep md => arg -> FilePath -> rep -> IO ()-printFileRep1 arg filepath r = printFile1 arg filepath (r,defaultMd1 arg r)--parseStringWith :: (Data rep, PadsMD md) => PadsParser (rep,md) -> String -> (rep,md)-parseStringWith p str = fst $ parseStringInput p str--parseFileWith :: (Data rep, PadsMD md) => PadsParser (rep,md) -> FilePath -> IO (rep,md)-parseFileWith p file = do- result <- CE.try (parseFileInput p file)- case result of- Left (e::CE.SomeException) -> return (gdef, replace_md_header gdef- (mkErrBasePD (E.FileError (show e) file) Nothing))- Right r -> return r--parseFileWithD :: (Data rep, PadsMD md) => S.RecordDiscipline -> PadsParser (rep,md) -> FilePath -> IO (rep,md)-parseFileWithD d p file = do- result <- CE.try (parseFileInputWithDisc d p file)- case result of- Left (e::CE.SomeException) -> return (gdef, replace_md_header gdef- (mkErrBasePD (E.FileError (show e) file) Nothing))- Right r -> return r--{- Generic function for computing the default for any type supporting Data a interface -}-getConstr :: DataType -> Constr-getConstr ty =- case dataTypeRep ty of- AlgRep cons -> head cons- IntRep -> mkIntegralConstr ty 0- FloatRep -> mkRealConstr ty 0.0- CharRep -> mkCharConstr ty '\NUL'- NoRep -> error "PADSC: Unexpected NoRep in PADS type"--gdef :: Data a => a-gdef = def_help- where- def_help- = let ty = dataTypeOf (def_help)- constr = getConstr ty- in fromConstrB gdef constr--ext2 :: (Data a, Typeable t)- => c a- -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2))- -> c a-ext2 def ext = maybe def id (dataCast2 ext)--newtype B x = B {unB :: x}--ext2B :: (Data a, Typeable t)- => a- -> (forall b1 b2. (Data b1, Data b2) => t b1 b2)- -> a-ext2B def ext = unB ((B def) `ext2` (B ext))----class BuildContainer2 c key item where- buildContainer2 :: [(key,item)] -> c key item- toList2 :: c key item -> [(key,item)]--instance Ord key => BuildContainer2 Map key a where- buildContainer2 = Map.fromList- toList2 = Map.toList--class BuildContainer1 c key item where- buildContainer1 :: [(key,item)] -> c (key, item)- toList1 :: c (key, item) -> [(key,item)]--instance (Ord a,Ord key) => BuildContainer1 Set key a where- buildContainer1 = Set.fromList- toList1 = Set.toList--instance BuildContainer1 [] key a where- buildContainer1 = id- toList1 = id-
@@ -1,63 +0,0 @@-{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune, ignore-exports #-}-{-|- Module : Language.Pads.Library.BigEndian- Description : Support for parsing of big endian data- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Library.BigEndian where--import Language.Pads.Padsc-import Language.Pads.Library.BinaryUtilities--import qualified Data.Int-import qualified Data.Word-import Data.ByteString as B---- * Signed Integers--- | type Int8 : 8-bit, signed integers-type Int8 = Data.Int.Int8-[pads| obtain Int8 from Bytes 1 using <|(bToi8sbh,i8Tobsbh)|> |]-bToi8sbh :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)-bToi8sbh p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)-i8Tobsbh (i,md) = (B.singleton (fromIntegral i), md)---- | type Int16 : signed byte high, 16-bit, signed integers-type Int16 = Data.Int.Int16-[pads| obtain Int16 from Bytes 2 using <| (bToi16sbh,i16sbhTob) |> |]-bToi16sbh p (bs,md) = (bytesToInt16 SBH bs, md)-i16sbhTob (i,md) = (int16ToBytes SBH i, md)---- | type Int32 : signed byte high, 32-bit, signed integers-type Int32 = Data.Int.Int32-[pads| obtain Int32 from Bytes 4 using <| (bToi32sbh,i32sbhTob) |> |]-bToi32sbh p (bs,md) = (bytesToInt32 SBH bs, md)-i32sbhTob (i,md) = (int32ToBytes SBH i, md)----- * Unsigned Integers (aka Words)--- | type Word8 : signed byte high, 8-bit, unsigned integers-type Word8 = Data.Word.Word8-[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]-bTow8 p (bytes,md) = (bytes `B.index` 0, md)-w8Tob (i,md) = (B.singleton i, md)---- | type Word16 : signed byte high, 16-bit, unsigned integers-type Word16 = Data.Word.Word16-[pads| obtain Word16 from Bytes 2 using <| (bTow16sbh,w16sbhTob) |> |]-bTow16sbh p (bs,md) = (bytesToWord16 SBH bs, md)-w16sbhTob (i,md) = (word16ToBytes SBH i, md)---- | type Word32 : signed byte high, 32-bit, unsigned integers-type Word32 = Data.Word.Word32-[pads| obtain Word32 from Bytes 4 using <| (bTow32sbh,w32sbhTob) |> |]-bTow32sbh p (bs,md) = (bytesToWord32 SBH bs, md)-w32sbhTob (i,md) = (word32ToBytes SBH i, md)-
@@ -1,114 +0,0 @@-{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Library.BinaryUtilities- Description : Utilities for transforming binary data- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Library.BinaryUtilities where--import Data.Int-import Data.Word-import Data.ByteString as B-import Data.Bits-import System.ByteOrder------------------------------------------------------------------------------------- | * Signed-Byte-High Functions--- The most significant digit is on the left (lowest address).--- These functions manage the case where the wire representation--- is signed-byte high, regardless of the endianness of the host--- machine.-data Endian = SBH | SBL | Native--bytesToInt16 :: Endian -> B.ByteString -> Int16-bytesToInt16 endian = fromIntegral . (bytesToWord16 endian)--int16ToBytes :: Endian -> Int16 -> B.ByteString-int16ToBytes endian = (word16ToBytes endian) . fromIntegral---bytesToInt32 :: Endian -> B.ByteString -> Int32-bytesToInt32 endian = fromIntegral . (bytesToWord32 endian)--int32ToBytes :: Endian -> Int32 -> B.ByteString-int32ToBytes endian = (word32ToBytes endian) . fromIntegral---bytesToWord16 :: Endian -> B.ByteString -> Word16-bytesToWord16 endian b =- let b0 :: Word16 = fromIntegral (b `B.index` 0)- b1 :: Word16 = fromIntegral (b `B.index` 1)- in- case (endian, byteOrder) of- (SBH, BigEndian) -> assembleWord16 (b1, b0)- (SBH, LittleEndian) -> assembleWord16 (b0, b1)- (SBL, BigEndian) -> assembleWord16 (b0, b1)- (SBL, LittleEndian) -> assembleWord16 (b1, b0)- (Native, BigEndian) -> assembleWord16 (b0, b1)- (Native, LittleEndian) -> assembleWord16 (b1, b0)---word16ToBytes :: Endian -> Word16 -> B.ByteString-word16ToBytes endian word16 =- let w0 :: Word8 = fromIntegral (shiftR (word16 .&. 0xFF00) 8)- w1 :: Word8 = fromIntegral (word16 .&. 0x00FF)- in case (endian, byteOrder) of- (SBH, BigEndian) -> B.pack [w1,w0]- (SBH, LittleEndian) -> B.pack [w0,w1]- (SBL, BigEndian) -> B.pack [w0,w1]- (SBL, LittleEndian) -> B.pack [w1,w0]- (Native, BigEndian) -> B.pack [w0,w1]- (Native, LittleEndian) -> B.pack [w1,w0]---assembleWord16 :: (Word16, Word16) -> Word16-assembleWord16 (b0, b1) = shift b0 8 .|. b1----bytesToWord32 :: Endian -> B.ByteString -> Word32-bytesToWord32 endian b =- let b0 :: Word32 = fromIntegral (b `B.index` 0)- b1 :: Word32 = fromIntegral (b `B.index` 1)- b2 :: Word32 = fromIntegral (b `B.index` 2)- b3 :: Word32 = fromIntegral (b `B.index` 3)- in- case (endian, byteOrder) of- (SBH, BigEndian) -> assembleWord32 (b3, b2, b1, b0)- (SBH, LittleEndian) -> assembleWord32 (b0, b1, b2, b3)- (SBL, BigEndian) -> assembleWord32 (b0, b1, b2, b3)- (SBL, LittleEndian) -> assembleWord32 (b3, b2, b1, b0)- (Native, BigEndian) -> assembleWord32 (b0, b1, b2, b3)- (Native, LittleEndian) -> assembleWord32 (b3, b2, b1, b0)---word32ToBytes :: Endian -> Word32 -> B.ByteString-word32ToBytes endian word32 =- let w0 :: Word8 = fromIntegral (shiftR (word32 .&. 0xFF000000) 24)- w1 :: Word8 = fromIntegral (shiftR (word32 .&. 0x00FF0000) 16)- w2 :: Word8 = fromIntegral (shiftR (word32 .&. 0x0000FF00) 8)- w3 :: Word8 = fromIntegral (word32 .&. 0x000000FF)- in case (endian, byteOrder) of- (SBH, BigEndian) -> B.pack [w3,w2,w1,w0]- (SBH, LittleEndian) -> B.pack [w0,w1,w2,w3]- (SBL, BigEndian) -> B.pack [w0,w1,w2,w3]- (SBL, LittleEndian) -> B.pack [w3,w2,w1,w0]- (Native, BigEndian) -> B.pack [w0,w1,w2,w3]- (Native, LittleEndian) -> B.pack [w3,w2,w1,w0]---assembleWord32 :: (Word32, Word32, Word32, Word32) -> Word32-assembleWord32 (b0, b1, b2, b3) =- shift b0 24 .|. shift b1 16 .|. shift b2 8 .|. b3----------------------------------------------------------------------------------
@@ -1,64 +0,0 @@-{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Library.LittleEndian- Description : Support for parsing of little endian data- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Library.LittleEndian where--import Language.Pads.Padsc-import Language.Pads.Library.BinaryUtilities--import qualified Data.Int-import qualified Data.Word-import Data.ByteString as B------------------------------------------------------------------------------------ * Signed Integers--- | type Int8 : signed byte low, 8-bit, signed integers-type Int8 = Data.Int.Int8-[pads| obtain Int8 from Bytes 1 using <|(bToi8,i8Tob)|> |]-bToi8 :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)-bToi8 p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)-i8Tob (i,md) = (B.singleton (fromIntegral i), md)---- | type Int16 : signed byte low, 16-bit, signed integers-type Int16 = Data.Int.Int16-[pads| obtain Int16 from Bytes 2 using <| (bToi16sbl,i16sblTob) |> |]-bToi16sbl p (bs,md) = (bytesToInt16 SBL bs, md)-i16sblTob (i,md) = (int16ToBytes SBL i, md)---- | type Int32 : signed byte low, 32-bit, signed integers-type Int32 = Data.Int.Int32-[pads| obtain Int32 from Bytes 4 using <| (bToi32sbl,i32sblTob) |> |]-bToi32sbl p (bs,md) = (bytesToInt32 SBL bs, md)-i32sblTob (i,md) = (int32ToBytes SBL i, md)------------------------------------------------------------------------------------ * Unsigned Integers (aka Words)--- | type Word8 : signed byte low, 8-bit, unsigned integers-type Word8 = Data.Word.Word8-[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]-bTow8 p (bytes,md) = (bytes `B.index` 0, md)-w8Tob (i,md) = (B.singleton i, md)--type Word16 = Data.Word.Word16--- | type Word16 : signed byte low, 16-bit, unsigned integers-[pads| obtain Word16 from Bytes 2 using <| (bTow16sbl,w16sblTob) |> |]-bTow16sbl p (bs,md) = (bytesToWord16 SBL bs, md)-w16sblTob (i,md) = (word16ToBytes SBL i, md)--type Word32 = Data.Word.Word32--- | type Word32 : signed byte low, 32-bit, unsigned integers-[pads| obtain Word32 from Bytes 4 using <| (bTow32sbl,w32sblTob) |> |]-bTow32sbl p (bs,md) = (bytesToWord32 SBL bs, md)-w32sblTob (i,md) = (word32ToBytes SBL i, md)-
@@ -1,78 +0,0 @@-{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Library.Native- Description : Support for parsing of native byte order data- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Library.Native where--import Language.Pads.Padsc-import Language.Pads.Library.BinaryUtilities--import qualified Data.Int-import qualified Data.Word-import Data.ByteString as B------------------------------------------------------------------------------------ * Signed Integers--- | type Int8 : 8-bit, signed integers-type Int8 = Data.Int.Int8-[pads| obtain Int8 from Bytes 1 using <|(bToi8,i8Tob)|> |]-bToi8 :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)-bToi8 p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)-i8Tob :: (Int8,Int8_md) -> (Bytes,Bytes_md)-i8Tob (i,md) = (B.singleton (fromIntegral i), md)----- | type Int16 : 16-bit, signed integers; bytes assembled in order-type Int16 = Data.Int.Int16-[pads| obtain Int16 from Bytes 2 using <| (bToi16,i16Tob) |> |]-bToi16 :: Span -> (Bytes,Bytes_md) -> (Int16,Int16_md)-bToi16 p (bs,md) = (bytesToInt16 Native bs, md)-i16Tob :: (Int16,Int16_md) -> (Bytes,Bytes_md)-i16Tob (i,md) = (int16ToBytes Native i, md)----- | type Int32 : 32-bit, signed integers; bytes assembled in order-type Int32 = Data.Int.Int32-[pads| obtain Int32 from Bytes 4 using <|(bToi32,i32Tob)|> |]-bToi32 :: Span -> (Bytes,Bytes_md) -> (Int32,Int32_md)-bToi32 p (bytes,md) = (bytesToInt32 Native bytes, md)-i32Tob :: (Int32,Int32_md) -> (Bytes,Bytes_md)-i32Tob (i,md) = (int32ToBytes Native i, md)------------------------------------------------------------------------------------ * Unsigned Integers (aka Words)--- | type Word8 : 8-bit, unsigned integers, raw order-type Word8 = Data.Word.Word8-[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]-bTow8 :: Span -> (Bytes,Bytes_md) -> (Word8,Word8_md)-bTow8 p (bytes,md) = (bytes `B.index` 0, md)-w8Tob :: (Word8,Word8_md) -> (Bytes,Bytes_md)-w8Tob (i,md) = (B.singleton i, md)---- | type Word16 : 16-bit, unsigned integers, raw order-type Word16 = Data.Word.Word16-[pads| obtain Word16 from Bytes 2 using <|(bTow16,w16Tob)|> |]-bTow16 :: Span -> (Bytes,Bytes_md) -> (Word16,Word16_md)-bTow16 p (bytes,md) = (bytesToWord16 Native bytes, md)-w16Tob :: (Word16,Word16_md) -> (Bytes,Bytes_md)-w16Tob (i,md) = (word16ToBytes Native i, md)---- | type Word32 : 32-bit, unsigned integers, raw order-type Word32 = Data.Word.Word32-[pads| obtain Word32 from Bytes 4 using <|(bTow32,w32Tob)|> |]-bTow32 :: Span -> (Bytes,Bytes_md) -> (Data.Word.Word32,Word32_md)-bTow32 p (bytes,md) = (bytesToWord32 Native bytes, md)-w32Tob :: (Data.Word.Word32,Word32_md) -> (Bytes,Bytes_md)-w32Tob (i,md) = (word32ToBytes Native i, md)--
@@ -1,136 +0,0 @@-{-# LANGUAGE Rank2Types, TypeFamilies, KindSignatures, NamedFieldPuns, DisambiguateRecordFields- , FlexibleInstances, DeriveDataTypeable, ConstraintKinds, MultiParamTypeClasses- , ScopedTypeVariables, FlexibleContexts #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.MetaData- Description : Metadata produced by a Pads parser- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- ---}-module Language.Pads.MetaData where--import qualified Language.Pads.Errors as E-import qualified Language.Pads.Source as S-import Text.PrettyPrint.Mainland as PP-import Text.PrettyPrint.Mainland.Class--import System.Posix.Types--import Data.Generics-import Data.Map (Map(..))-import qualified Data.Map as Map-import Data.Set (Set(..))-import qualified Data.Set as Set-import Data.List---- | Base type library support for internal (to Pads) metadata-data Base_md = Base_md { numErrors :: Int- , errInfo :: Maybe E.ErrInfo- -- Need to add location information, etc.- }- deriving (Typeable, Data, Eq, Ord, Show)----- | Meta data type class-class Data md => PadsMD md where- get_md_header :: md -> Base_md- replace_md_header :: md -> Base_md -> md---- | The trivial case for when the Pads parser doesn't need to add any metadata.-instance PadsMD Base_md where- get_md_header b = b- replace_md_header old new = new---- | If we have a 2-tuple where the first thing is of type Base_md, then the tuple--- itself is a Pads metadata instance.-instance Data b => PadsMD (Base_md,b) where- get_md_header (h,b) = h- replace_md_header (h1,b) h2 = (h2,b)---- | Default metadata instance with no errors being reported.-cleanBasePD = Base_md {numErrors = 0, errInfo = Nothing }---- | Default metadata instance with a generic "file error" being reported.-errorBasePD msg path = Base_md {numErrors = 1, errInfo = Just (E.ErrInfo (E.FileError msg path) Nothing) }---- | Metadata merge-mergeBaseMDs :: [Base_md] -> Base_md-mergeBaseMDs mds = foldl addInfo cleanBasePD mds- where- addInfo (Base_md {numErrors=num1,errInfo=i1})- (Base_md {numErrors=num2,errInfo=i2})- = Base_md {numErrors=num1 + num2, errInfo= E.maybeMergeErrInfo i1 i2 }---- | Metadata for a single parse error occuring at some location 'Loc'.-mkErrBasePDfromLoc msg loc- = Base_md {numErrors = 1,- errInfo = Just (E.ErrInfo{msg=msg,position= Just (S.locToSpan loc)}) }---- | Metadata for a single parse error occuring at some position 'Span'.-mkErrBasePD msg pos- = Base_md {numErrors = 1,- errInfo = Just (E.ErrInfo{msg=msg,position= pos}) }--instance Pretty Base_md where- ppr = pprBaseMD---- | Pretty printer for the base metadata type.-pprBaseMD Base_md {numErrors=num, errInfo = info}- = text "Errors:" <+> ppr num <+>- case info of- Nothing -> PP.empty- Just e -> ppr e--type family Meta (rep :: *) :: *---- | Fancy 'Generic' magic for defining a function that produces a default value--- for any type so long as that type is an instance of Data. We do this by--- selecting the first alternative of algebraic data types and recursively--- filling in any nested types with default values as well. For instance:------ > > :set -XDeriveDataTypeable--- > > type Bar = (Int,Char)--- > > data Foo = A Bar Bar | B | C deriving (Data, Show)--- > > myempty :: Foo--- > A (0,'\NUL') (0,'\NUL')-myempty :: forall a. Data a => a-myempty = general- `extB` char- `extB` int- `extB` integer- `extB` float- `extB` double- `extB` coff- `extB` epochTime- `extB` fileMode- `ext2B` map- `ext1B` set- `ext1B` list where- -- Generic case- general :: Data a => a- general = fromConstrB myempty (indexConstr (dataTypeOf general) 1)-- -- Base cases- char = '\NUL'- int = 0 :: Int- integer = 0 :: Integer- float = 0.0 :: Float- double = 0.0 :: Double- coff = 0 :: COff- epochTime = 0 :: EpochTime- fileMode = 0 :: FileMode- list :: Data b => [b]- list = []- map :: (Data k,Data v) => Map k v- map = Map.empty- set :: Data k => Set k- set = Set.empty-
@@ -1,534 +0,0 @@-{-# LANGUAGE NamedFieldPuns #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.PadsParser- Description : The parsing monad for Pads- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- These are the combinators used to build PADS parsers. In this module we define- the 'PadsParser' parsing monad which operates in a model where each parsing- step (bind in the monad) runs a function `f :: Source -> (a, Source)`. This is- similar to how the 'Read' typeclass implements parsing where we return the thing- parsed by `f` of type `a` along with the remainder source input of type- `Source`.-- Some important notes for future developers:- - 'primPads' and 'queryP' below let you define new PadsParsers using Haskell- functions without having to crack open the monad yourself.- - As soon as the monad encounters a failure, we stop parsing and return the- parsed result as far as we got in the input string.---}--module Language.Pads.PadsParser where--import qualified Language.Pads.Source as S-import Language.Pads.Errors-import Language.Pads.MetaData-import Language.Pads.RegExp-import Data.Char-import Data.Word--import Control.Applicative (Applicative(..))-import Control.Monad---- | Take a 'PadsParser' for some type and an input 'String' and parse the--- 'String' using the 'PadsParser'.-parseStringInput :: PadsParser a -> String -> (a,String)-parseStringInput pp cs =- let ((r,rest),b) = pp # S.padsSourceFromString cs- in (r, S.padsSourceToString rest)---- | Same as 'parseStringInput' but with a 'RawStream' source as input.-parseByteStringInput :: PadsParser a -> S.RawStream -> (a, S.RawStream)-parseByteStringInput pp cs =- let ((r,rest),b) = pp # S.padsSourceFromByteString cs- in (r, S.padsSourceToByteString rest)---- | Same as 'parseStringInput' but with a 'FilePath' as input and 'IO' output.-parseFileInput :: PadsParser a -> FilePath -> IO a-parseFileInput pp file = do- source <- S.padsSourceFromFile file- let ((r,rest),b) = pp # source- return r---- | Same as 'parseFileInput' but with the ability to specify a non-default--- record discipline.-parseFileInputWithDisc :: S.RecordDiscipline -> PadsParser a -> FilePath -> IO a-parseFileInputWithDisc d pp file = do- source <- S.padsSourceFromFileWithDisc d file- let ((r,rest),b) = pp # source- return r------------------------------------------------------------------------------------ * The Pads Parsing Monad---- | A Pads parser is a function over inputs to some type `a` and the remaining--- input.-newtype PadsParser a = PadsParser { (#) :: S.Source -> Result (a,S.Source) }---- | A Pads parse result is just a tuple of the type parsed and a boolean--- indicating whether or not a parse error occured. If the boolean is False,--- the result type has been populated with default values. See--- "Language.Pads.Generic" for the type class implementing default values, and--- "Language.Pads.CoreBaseTypes" for definitions of default values for the--- built-in types.-type Result a = (a,Bool)---- | A Pads parser can be mapped over, which just says we need to run the--- parser, grab the resulting parsed value, and apply the function we're mapping--- to that result.-instance Functor PadsParser where- fmap f p = PadsParser $ \bs -> let ((x,bs'),b) = p # bs in- ((f x, bs'),b)---- | This monad instance for Pads parsers looks just like any other sequencing--- monad (run the first one and pipe the result into the second) with one thing--- added: if any results on the way are bad, then the whole parse is bad.-instance Monad PadsParser where- return r = PadsParser $ \bs -> ((r,bs), True)- p >>= f = PadsParser $ \bs -> let ((v,bs'),b) = p # bs- ((w,bs''),b') = f v # bs'- in ((w,bs''), b && b')---- | Applicative instance for 'PadsParser' to satisfy GHC-instance Applicative PadsParser where- pure = return- (<*>) = ap---- | A pads parsing combinator used by other pads parsers when they detect a--- parse error.-badReturn r = PadsParser $ \bs -> ((r,bs), False)---- | -mdReturn (rep,md) = PadsParser $- \bs -> (((rep,md),bs), numErrors (get_md_header md) == 0)---- | Construct a Pads parser which always returns the given value and metadata--- reporting no errors.-returnClean :: t -> PadsParser (t, Base_md)-returnClean x = return (x, cleanBasePD)---- | Construct a Pads parser which always reports the given error message along--- with returning a (likely default) value given to us.-returnError :: t -> ErrMsg -> PadsParser (t, Base_md)-returnError x err = do loc <- getLoc- badReturn (x, mkErrBasePDfromLoc err loc)--infixl 5 =@=, =@---- | -(=@=) :: PadsParser (t3 -> t2, t1 -> t)- -> PadsParser (t3, t1)- -> PadsParser (t2, t)-p =@= q = do - (f,g) <- p- (rep,md) <- q- return (f rep, g md)--(=@) :: PadsParser (t3, t2 -> t1)- -> PadsParser (t, t2)- -> PadsParser (t3, t1)-p =@ q = do- (f,g) <- p- (rep,md) <- q- return (f, g md)------------------------------------------------------------------------------------ * Source manipulation functions---- | Run a pure function on the current source input from inside the--- 'PadsParser' monad. Used for detecting things like 'isEOF', 'isEOR', or for--- peaking at the current head of the input with 'peekHeadP'.-queryP :: (S.Source -> a) -> PadsParser a-queryP f = PadsParser $ \bs -> ((f bs,bs), True)---- | Run a pure function to mutate the current input source.-primPads :: (S.Source -> (a,S.Source)) -> PadsParser a-primPads f = PadsParser $ \bs -> (f bs, True)---- | Lift a function which runs in the 'Maybe' monad to run in the 'PadsParser'--- monad with the same semantics as 'primPads', with the added ability that a--- Nothing produces a parse failure.-liftStoP :: (S.Source -> Maybe (a,S.Source)) -> a -> PadsParser a-liftStoP f def = PadsParser $ \bs ->- case f bs of- Nothing -> ((def,bs), False)- Just (v,bs') -> ((v,bs'), True)---- | Replace the source in the given 'Result' with the given 'Source'-replaceSource :: S.Source -> Result (a,S.Source) -> Result (a,S.Source)-replaceSource bs ((v,_),b) = ((v,bs),b)------------------------------------------------------------------------------------ * Monad choice combinators---- The monad is non-backtracking. The only choice point is at ChoiceP---- | One-by-one try a list of parsers in order until you find the one that works--- and return that one. If none of them work, return the last one that failed.-choiceP :: [PadsParser a] -> PadsParser a-choiceP ps = foldr1 (<||>) ps---- | Try the first parser and if it fails, try the second parser-(<||>) :: PadsParser a -> PadsParser a -> PadsParser a-p <||> q = PadsParser $ \bs -> (p # bs) <++> (q # bs)---- | Grab the first result if it succeeded, otherwise use the second one-(<++>) :: Result a -> Result a -> Result a-(r, True) <++> _ = (r, True)-(r1, False) <++> r2 = r2 -- A number of functions rely on this being r2------------------------------------------------------------------------------------- | Run the given Pads parser on the current input, but after running it--- replace the (now possibly mutated input) with the original input while--- returning the result parsed.-parseTry :: PadsMD md => PadsParser (rep,md) -> PadsParser (rep,md)-parseTry p = do- (rep, md) <- PadsParser $ \bs -> replaceSource bs (p # bs)- mdReturn (rep, md)------------------------------------------------------------------------------------ * Parsers for Pads language features---- | This is where constraint predicates get run and converted into error--- messages upon predicate failure.-parseConstraint :: PadsMD md =>- PadsParser(rep,md) -> (rep -> md -> Bool) -> PadsParser(rep, md)-parseConstraint p pred = do- (rep,md) <- p- mdReturn (rep, replace_md_header md (constraintReport (pred rep md) md))---- | Convert the result of running a Pads constraint predicate into an error--- message.-constraintReport :: PadsMD md => Bool -> md -> Base_md-constraintReport isGood md = Base_md {numErrors = totErrors, errInfo = errors}- where- Base_md {numErrors, errInfo} = get_md_header md- totErrors = if isGood then numErrors else numErrors + 1- errors = if totErrors == 0 then Nothing else- Just(ErrInfo {msg = if isGood then UnderlyingTypedefFail- else PredicateFailure,- position = join $ fmap position errInfo})------------------------------------------------------------------------------------- | Run the given parser and transform the result using the given Haskell--- function, which originally looked like this in Pads syntax:------ > type Foo = transform Bar => Baz using <|(bar2baz, baz2bar)|>------ The first function in the antiquoted tuple (bar2baz) is run here, whereas the--- second function in the tuple (baz2bar) is used during pretty printing.-parseTransform :: PadsMD dmd =>- PadsParser (sr,smd) -> (S.Span->(sr,smd)->(dr,dmd)) -> PadsParser (dr,dmd)-parseTransform sParser transform = do- begin_loc <- getLoc- src_result <- sParser- end_loc <- getLoc- let src_pos = S.locsToSpan begin_loc end_loc- return (transform src_pos src_result)------------------------------------------------------------------------------------- | Run a parser with the appropriate record discipline enabled in the parsing--- monad. See the 'RecordDiscipline' data type for the available disciplines--- along with appropriate Haskell functions that can be referenced from a Pads--- partition expression, e.g.:------ > type Foo = partition Bar using none------ Note that the record discipline specified in a partition expression remains--- active until the parsing monad encounters another partition expression. This--- effectively means that record disciplines form a stack that get popped off as--- parsers complete. This stack however is implemented as scoped variables in--- nested calls of this function rather than as a Haskell stack stored in the--- monad.-parsePartition :: PadsMD md =>- PadsParser(rep,md) -> S.RecordDiscipline -> PadsParser(rep, md)-parsePartition p newDisc = do- oldDisc <- queryP S.getRecordDiscipline- primPads (S.setRecordDiscipline newDisc)- x <- p- primPads (S.setRecordDiscipline oldDisc)- return x------------------------------------------------------------------------------------- | -parseListNoSepNoTerm :: PadsMD md =>- PadsParser (rep,md) -> PadsParser ([rep], (Base_md, [md]))-parseListNoSepNoTerm p = listReport (parseMany p)---- | -parseListSepNoTerm :: (PadsMD md, PadsMD mdSep) =>- PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))-parseListSepNoTerm sep p = listReport (parseManySep sep p)---- | -parseListNoSepLength :: (PadsMD md) =>- Int -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))-parseListNoSepLength i p = listReport (parseCount i p)---- | -parseListSepLength :: (PadsMD md, PadsMD mdSep) =>- PadsParser (repSep,mdSep) -> Int -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))-parseListSepLength sep n p = listReport (parseCountSep n sep p)---- | -parseListNoSepTerm :: (PadsMD md, PadsMD mdTerm) =>- PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))-parseListNoSepTerm term p = listReport (parseManyTerm term p)---- | -parseListSepTerm :: (PadsMD md, PadsMD mdSep, PadsMD mdTerm) =>- PadsParser (repSep,mdSep) -> PadsParser (repTerm,mdTerm) ->- PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))-parseListSepTerm sep term p = listReport (parseManySepTerm sep term p)---- | -listReport :: PadsMD b => PadsParser [(a, b)] -> PadsParser ([a], (Base_md, [b]))-listReport p = do- listElems <- p- let (reps, mds) = unzip listElems- let hmds = map get_md_header mds- return (reps, (mergeBaseMDs hmds, mds))------------------------------------------------------------------------------------- | Parse zero or more instances of the given parser. Stop parsing when the--- parser encounters something it is unable to parse properly. This means,--- during a valid parse, we attempt to parse more of the input than we really--- should and only given up when there isn't a single valid parse.-parseMany :: PadsMD md => PadsParser (rep,md) -> PadsParser [(rep,md)]-parseMany p = do (r,m) <- p- if (numErrors (get_md_header m) == 0)- then do { rms <- parseMany p- ; return ((r,m) : rms)}- else badReturn []-- <||> return []---- | Parse one or more instances of the given parser.-parseManySep :: (PadsMD md, PadsMD mdSep) => PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseManySep sep p = do { rm <- p- ; rms <- parseManySep1 sep p- ; return (rm : rms)- }---- | Parse zero or more instances of the given parser. TODO: The name of this--- and 'parseManySep' are misleading / should be swapped?-parseManySep1 :: (PadsMD md, PadsMD mdSep) => PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseManySep1 sep p = do (r,m) <- sep- if (numErrors (get_md_header m) == 0)- then parseManySep sep p- else badReturn []- <||> return []------------------------------------------------------------------------------------- | Parse n instances of the given parser.-parseCount :: (PadsMD md) => Int -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseCount n p = sequence (replicate n p)---- | Parse n instances of the given parser with another parser acting as the--- separator between instances of the first parser. Note that this properly--- intersperses the separator -parseCountSep :: (PadsMD md) =>- Int -> PadsParser rmdSep -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseCountSep n sep p | n <= 0 = return []-parseCountSep n sep p = do- rm <- p- rms <- sequence $ replicate (n-1) (sep >> p)- return (rm:rms)------------------------------------------------------------------------------------- | Parse many instances of the given parser until we see an instance of the--- terminator parser. Parsing satisfies the following rules in decreasing order--- of precedence:--- * If we see the terminator, parse it and stop parsing (even if the terminator--- is ambiguous with the given parser).--- * If we see the end of file, stop parsing and return what we've parsed thus--- far.--- * Parse an instance of the given parser and recurse.-parseManyTerm :: (PadsMD md, PadsMD mdTerm) =>- PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseManyTerm term p = (term >> return [])- <||> (ifEOFP >> return [])- <||> do { rm <- p- ; rms <- parseManyTerm term p- ; return (rm:rms) }---- | Like 'parseManyTerm' but with a separator in-between instances of the given--- parser.-parseManySepTerm :: (PadsMD md, PadsMD mdSep, PadsMD mdTerm) =>- PadsParser (repSep,mdSep) -> PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser [(rep,md)]-parseManySepTerm sep term p = (term >> return [])- <||> (ifEOFP >> return [])- <||> scan- where- scan = do (rep, md) <- p- (terminated,junk) <- seekSep sep term- case junk of- [] -> if terminated then return [(rep,md)] else- do rms <- scan- return ((rep,md):rms)- _ -> do sepLoc <- getLoc- let report = junkReport md sepLoc junk- if terminated then- badReturn [(rep,report)]- else do- rms <- scan- badReturn ((rep,report) : rms)---- | Consume input until we find the terminator, separator, end-of-file, or--- end-of-record. If we find (in decreasing order of precedence):--- * The terminator, then report that we successfully terminated--- * The end-of-file, report successful termination.--- * The separator, report that we successfully seeked until a separator was--- consumed from the input.--- * An end-of-record symbol, report a bad parse------ Note that the fact that we report successful termination upon end-of-file is--- probably a bug, because it means we report a successful parse even though we--- didn't find the terminator to the list being parsed.-seekSep sep term = (term >> return (True, []))- <||> (ifEOFP >> return (True, []))- <||> (sep >> return (False, []))- <||> do { b <- isEORP- ; if b then badReturn (False, []) else- do { c <- takeHeadP- ; (b,cs) <- seekSep sep term- ; badReturn (b, c:cs)- }- }---- | -junkReport md loc junk = replace_md_header md mergeMD- where- mdSep = mkErrBasePDfromLoc (ExtraStuffBeforeTy junk "separator" ) loc- mergeMD = mergeBaseMDs [get_md_header md, mdSep]------------------------------------------------------------------------------------- | Get the current source location offset into the data we're currently--- parsing.-getLoc :: PadsParser S.Loc-getLoc = queryP S.getSrcLoc--isEOFP, isEORP :: PadsParser Bool-isEOFP = queryP S.isEOF-isEORP = queryP S.isEOR--ifEOFP, ifEORP :: PadsParser ()-ifEOFP = do { b <- isEOFP; if b then return () else badReturn ()}-ifEORP = do { b <- isEORP; if b then return () else badReturn ()}---- | Remove and return the first n characters from the input source-takeP :: Integral a => a -> PadsParser String-takeP n = primPads (S.take (fromInt n))---- | Remove and return the first n bytes from the input source-takeBytesP :: Integral a => a -> PadsParser S.RawStream-takeBytesP n = primPads (S.takeBytes (fromInt n))--takeBytesNBP :: Integral a => a -> PadsParser S.RawStream-takeBytesNBP n = primPads (S.takeBytesNB (fromInt n))--takeBitsP :: Integral a => a -> PadsParser Integer-takeBitsP b = primPads (S.takeBits (fromInt b))--takeBits8P :: Integral a => a -> PadsParser Word8-takeBits8P b = primPads (S.takeBits8 (fromInt b))--takeBits16P :: Integral a => a -> PadsParser Word16-takeBits16P b = primPads (S.takeBits16 (fromInt b))--takeBits32P :: Integral a => a -> PadsParser Word32-takeBits32P b = primPads (S.takeBits32 (fromInt b))--takeBits64P :: Integral a => a -> PadsParser Word64-takeBits64P b = primPads (S.takeBits64 (fromInt b))--fromInt :: (Integral a1, Num a) => a1 -> a-fromInt n = fromInteger $ toInteger n------------------------------------------------------------------------------------- | Query the current symbol (character) of input-peekHeadP :: PadsParser Char-peekHeadP = queryP S.head---- | Remove and return the current symbol (character) of input-takeHeadP :: PadsParser Char-takeHeadP = primPads S.takeHead---- | See 'takeHeadStr' - returns false in the PadsParser monad iff the front of--- current source matches the given string with the side effect of removing that--- string from the front of the source if it does.-takeHeadStrP :: String -> PadsParser Bool-takeHeadStrP str = primPads (S.takeHeadStr str)---- Return string is junk before found string-scanStrP :: String -> PadsParser (Maybe String)-scanStrP str = primPads (S.scanStr str)---regexMatchP ::RE -> PadsParser (Maybe String)-regexMatchP re = primPads (S.regexMatch re)--regexStopP :: RE -> PadsParser (Maybe String)-regexStopP re = primPads (S.regexStop re)--scanP :: Char -> PadsParser Bool-scanP c = primPads (\s -> let (f,r,e) = S.scanTo c s in (f,r))--getAllP :: PadsParser String-getAllP = primPads S.drainSource--getAllBinP :: PadsParser S.RawStream-getAllBinP = primPads S.rawSource--drainSourceNBP :: PadsParser String-drainSourceNBP = primPads S.drainSourceNB--satisfy p = primPads loop- where loop s = if S.isEOF s || S.isEOR s then ([],s) else- let c = S.head s in- if p c then- let (xs,s') = loop (S.tail s) in- (c:xs, s')- else- ([],s)--satisfyNBP :: (Char -> Bool) -> (PadsParser String)-satisfyNBP p = primPads (S.satisfyNB p)--digitListToInt :: Bool -> [Char] -> Int-digitListToInt isNeg digits = if isNeg then negate raw else raw- where- raw = foldl (\a d ->10*a + digitToInt d) 0 digits-----------------------------------------------------------------------------------doLineBegin :: PadsParser ((), Base_md)-doLineBegin = do- rbegErr <- primPads S.srcLineBegin- case rbegErr of- Nothing -> returnClean ()- Just err -> returnError () (LineError err)---doLineEnd :: PadsParser ((), Base_md)-doLineEnd = do- rendErr <- primPads S.srcLineEnd- case rendErr of- Nothing -> returnClean ()- Just err -> returnError () (LineError err)
@@ -1,123 +0,0 @@-{-# LANGUAGE FlexibleContexts, DeriveDataTypeable #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.PadsPrinter- Description : Lazy Pads printing monad- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- This module provides a way to lazily append to a ByteString for the purpose- of printing said ByteString.---}-module Language.Pads.PadsPrinter where--import qualified Data.ByteString as B-import qualified Language.Pads.Source as S-import qualified Data.List as List-import Language.Pads.Errors-import Data.Typeable-import Language.Pads.MetaData-import Data.Data--{- Printing Monad -}---- | -type PadsPrinter a = a -> FList---- Lazy append-lists---- | -type FList = B.ByteString -> B.ByteString---- | -(+++) :: FList -> FList -> FList-p +++ q = p . q---- | -nil :: FList-nil = id---- | -concatFL :: [FList] -> FList-concatFL (f:fs) = foldr (+++) nil fs---- | -printNothing :: FList-printNothing ws = ws---- | -addBString :: B.ByteString -> FList-addBString bs = B.append bs---- | -addString :: String -> FList-addString s = B.append (S.strToByteString s)---- | -fshow :: Show a => a -> FList-fshow x = B.append (S.strToByteString (show x))---- | -printEOR :: FList-printEOR = addString ['\n']---- | -printEOF :: FList-printEOF = addString []---- | -endRecord :: FList -> FList-endRecord fst = fst +++ printEOR---- | -printF :: FList -> IO ()-printF q = Prelude.print (B.unpack (q B.empty))------------------------------------------------------printList' (reps, (_,mds)) printItem printSep printTerm = (concatFL (List.intersperse printSep (map printItem (zip reps $ mds ++ repeat myempty))) ) +++ printTerm--printList :: (Data r,Data m) => (PadsPrinter (r,m)) -> FList -> FList -> ([r], (Base_md,[m])) -> FList-printList printItem printSep printTerm (reps, (_,mds)) =- (concatFL (List.intersperse printSep (map printItem (zip reps $ mds ++ repeat myempty))) )- +++ printTerm--{-----type IntPair = (Int,"|",Int)--=====>--type IntPair = (Int, Int)-type IntPair_md = (Base_md, (Base_md, Base_md))--intPair_parseM- = let- f_rep x1 x3 = (x1, x3)- f_md x1 x2 x3- = (mergeBaseMDs- [get_md_header x1, get_md_header x2, get_md_header x3],- (x1, x3))- in- (((return (f_rep, f_md) =@= int_parseM) =@ strLit_parseM "|")- =@=- int_parseM)--intPair_parseS = parseStringInput intPair_parseM]--intPair_printFL (r,m)- = case (r,m) of- ((r1,r2),(_,(m1,m2)))- -> int_PrintFL (r1,m1) +++- addString "|" +++- int_PrintFL (r2,m2)---}-
@@ -1,59 +0,0 @@-{-# LANGUAGE TypeSynonymInstances, GeneralizedNewtypeDeriving, QuasiQuotes, TemplateHaskell, DeriveDataTypeable,- ScopedTypeVariables, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,- UndecidableInstances, NamedFieldPuns, RecordWildCards, StandaloneDeriving #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Padsc- Description : Pads compiler- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- This module re-exports all the modules necessary to make use of the Pads- quasiquoter and compilation infrastructure.---}-module Language.Pads.Padsc (- {- FIX: Languages.Pads.Source exports "take", which clashes with- the function of the same name in Prelude -}- module Language.Pads.Source,- module Language.Pads.RegExp,- module Language.Pads.Errors,- module Language.Pads.PadsParser,- module Language.Pads.MetaData,- module Language.Pads.Generic,- module Language.Pads.CoreBaseTypes,- module Language.Pads.Quote,- module Language.Pads.Syntax,- module Language.Pads.BaseTypes,- module Language.Pads.Pretty,- module Language.Pads.PadsPrinter,- module Data.Data,- ppr, pretty- )- where--import Language.Pads.Source-import Language.Pads.RegExp-import Language.Pads.Errors hiding (msg)-import Language.Pads.PadsParser-import Language.Pads.MetaData-import Language.Pads.Generic-import Language.Pads.CoreBaseTypes-import Language.Pads.Quote-import Language.Pads.Syntax-import Language.Pads.BaseTypes-import Language.Pads.Pretty-import Language.Pads.PadsPrinter--import Data.Data-import Text.PrettyPrint.Mainland hiding (line, dot)-import Text.PrettyPrint.Mainland.Class--{- Fix these should be reexported -}--- parseAllS = Language.Pads.PadsParser.parseAllS-numErrors = Language.Pads.MetaData.numErrors-
@@ -1,439 +0,0 @@-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Parser- Description : Parser for the syntax of Pads- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- This module implements the parser for the PADS syntax in Haskell using parser- combinators.--}-module Language.Pads.Parser where--import Language.Pads.Syntax---import Text.Parsec hiding (upper,lower)-import qualified Text.Parsec.String as PS-import Text.Parsec.Error-import Text.Parsec.Prim as PP-import qualified Text.Parsec.Token as PT-import Text.Parsec.Language-import Text.ParserCombinators.Parsec.Language-import Text.ParserCombinators.Parsec.Pos-import Text.Parsec.Expr-import Control.Monad--import qualified Language.Haskell.Meta as LHM-import Language.Haskell.TH--import Data.Char-import System.FilePath.Glob----type Parser = PS.Parser-type Env = [String]---- | The main entry point for the Pads QuasiQuoter-parsePadsDecls :: SourceName -> Line -> Column -> String -> Either ParseError [PadsDecl]-parsePadsDecls fileName line column input- = PP.parse (do { setPosition (newPos fileName line column)- ; whiteSpace- ; x <- padsDecls- ; whiteSpace- ; eof <|> errorParse- ; return x- }) fileName input--errorParse = do- { rest <- manyTill anyToken eof- ; unexpected rest }------------------------------------------------------------------------------------ * PADS DECLARATIONS--padsDecls :: Parser [PadsDecl]-padsDecls = option [] (many1 topDecl)--topDecl :: Parser PadsDecl-topDecl- = typeDecl <|> dataDecl <|> newDecl <|> obtainDecl- <?> "Pads declaration keyword"--typeDecl :: Parser PadsDecl-typeDecl- = do { reserved "type"- ; (id,env) <- declLHS; pat <- patLHS- ; rhs <- ptype env- ; return (PadsDeclType id env pat rhs)- } <?> "Pads type declaration"--dataDecl :: Parser PadsDecl-dataDecl- = do { reserved "data"- ; (id,env) <- declLHS; pat <- patLHS- ; rhs <- dataRHS env; drvs <- option [] derives- ; return (PadsDeclData id env pat rhs drvs)- } <?> "Pads data declaration"--newDecl :: Parser PadsDecl-newDecl- = do { reserved "newtype"- ; (id,env) <- declLHS; pat <- patLHS- ; rhs <- newRHS env; drvs <- option [] derives- ; return (PadsDeclNew id env pat rhs drvs)- } <?> "Pads newtype declaration"--obtainDecl :: Parser PadsDecl-obtainDecl- = do { reserved "obtain"- ; (id,env) <- declLHS- ; reservedOp "from"; rhs <- ptype env- ; reserved "using"; exp <- expression- ; return (PadsDeclObtain id env rhs exp)- } <?> "Pads transform type"--declLHS- = do { id <- upper; env <- try $ many lower- ; return (id,env)- }--patLHS- = do { p <- try $ haskellParsePatTill "="- ; return (Just p)- }- <|> (reservedOp "=" >> return Nothing)--derives- = reserved "deriving" >>- (do { q <- qualUpper; return [q] }- <|> parens (commaSep1 qualUpper))------------------------------------------------------------------------------------ * PADS TYPES--ptype :: Env -> Parser PadsTy-ptype env- = constrain env- <|> obtain env- <|> partition env- <|> listTy env- <|> value env- <|> btype env- <?> "Pads Pads type expression"--constrain :: Env -> Parser PadsTy-constrain env- = do { reserved "constrain"- ; pat <- haskellParsePatTill "::"; ty <- ptype env- ; exp <- predic- ; return (PConstrain pat ty exp)- } <?> "Pads constrain type"--predic = do { reservedOp "where"; expression }--obtain :: Env -> Parser PadsTy-obtain env- = do { reserved "obtain"; dst <- ptype env- ; reservedOp "from"; src <- ptype env- ; reserved "using"; exp <- expression- ; return (PTransform src dst exp)- } <?> "Pads transform type"--partition :: Env -> Parser PadsTy-partition env- = do { reserved "partition"; ty <- ptype env- ; reserved "using"; exp <- expression- ; return (PPartition ty exp)- } <?> "Pads partition type"--listTy :: Env -> Parser PadsTy-listTy env- = do { (elm,sepM) <- brackets (listInside env)- ; termM <- listEnd env- ; return (PList elm sepM termM)- } <?> "Pads list type"--listInside env- = do { elm <- ptype env- ; sepM <- optionMaybe (reservedOp "|" >> ptype env)- ; return (elm,sepM)- }--listEnd env- = optionMaybe- ( do {reservedOp "terminator"; t<-ptype env; return (LTerm t)}- <|> do {reservedOp "length"; e<-expression; return (LLen e)})--value env- = do { reserved "value"- ; exp <- expression; reservedOp "::"- ; ty <- ptype env- ; return (PValue exp ty)- }---btype :: Env -> Parser PadsTy-btype env- = try $ do- { ty <- etype env; tys <- many (atype env)- ; expM <- optionMaybe (try expression);- ; if length tys==0 && expM == Nothing- then return ty- else return (PApp (ty:tys) expM) }--etype :: Env -> Parser PadsTy-etype env = atype env- <|> try (expression >>= (return . PExpression))--atype env- = try (tuple env)- <|> do { (elm,sepM) <- brackets (listInside env)- ; return (PList elm sepM Nothing)}- <|> fmap PTycon qualUpper- <|> fmap PTyvar (tyvar env)--tuple :: Env -> Parser PadsTy-tuple env- = do { tys <- parens $ option [] (commaSep1 (ptype env))- ; case length tys of- 0 -> return (PTycon ["Void"])- 1 -> return (head tys)- _ -> return (PTuple tys)- }- <?> "Pads tuple type"------------------------------------------------------------------------------------ * PADS DATA DECLARATIONS--dataRHS :: Env -> Parser PadsData-dataRHS env- = switchTy env- <|> fmap PUnion (constrs env)- <?> "Pads data type right hand side"--switchTy :: Env -> Parser PadsData-switchTy env- = do { reservedOp "case"; exp <- expression- ; reservedOp "of"; brs <- branch env `sepBy1` reservedOp "|"- ; return (PSwitch exp brs)- } <?> "Pads switch type"--branch :: Env -> Parser (Pat, BranchInfo)-branch env- = do { pat <- haskellParsePatTill "->"; br <- constr env- ; return (pat, br)- } <?> "Pads switch branch"--constrs :: Env -> Parser [BranchInfo]-constrs env = constr env `sepBy1` reservedOp "|"--constr :: Env -> Parser BranchInfo-constr env- = do { id <- upper;- ; do { args <- record env; predM <- optionMaybe predic- ; return (BRecord id args predM)}- <|> do { args <- option (mkId id) (constrArgs env)- ; predM <- optionMaybe predic- ; return (BConstr id args predM)}}- where- mkId id = [(NotStrict, PExpression (LitE (StringL id)))]- -- Provides the expansion e.g.: Tue -> Tue "Tue"---constrArgs :: Env -> Parser [ConstrArg]-constrArgs env- = many1 $ do- { bang <- option NotStrict (reservedOp "!" >> return IsStrict)- ; ty <- etype env- ; return (bang,ty)- }---record :: Env -> Parser [FieldInfo]-record env- = do { reservedOp "{"- ; flds <- field env `sepBy` reservedOp ","- ; reservedOp "}"- ; return flds- } <?> "Pads record type"--field :: Env -> Parser FieldInfo-field env- = try (do { id <- (lower << reservedOp "::")- ; ty <- ftype env- ; predM <- optionMaybe predic- ; return (Just id, ty, predM)- })- <|> try (do { id <- lower; reservedOp "="- ; reserved "value"- ; exp <- expression; reservedOp "::"- ; (strict,ty) <- ftype env- ; predM <- optionMaybe predic- ; return (Just id, (strict, PValue exp ty), predM)- })- <|> do { ty <- ftype env- ; let recordid = (case ty of- (strict,PConstrain (VarP name) _ _) -> Just $ nameBase name- otherwise -> Nothing- )- ; predM <- optionMaybe predic- ; return (recordid, ty, predM)- }- <?> "record field"--ftype env- = do { reservedOp "!"; ty <- atype env; return (IsStrict,ty)}- <|> do { ty <- ptype env; return (NotStrict,ty)}------------------------------------------------------------------------------------ * PADS NEW TYPE DECLARATIONS--newRHS :: Env -> Parser BranchInfo-newRHS env- = do { id <- upper;- ; do { rec <- record1 env- ; predM <- optionMaybe predic- ; return (BRecord id rec predM)}- <|> do { arg <- atype env- ; predM <- optionMaybe predic- ; return (BConstr id [(NotStrict,arg)] predM)- }- }--record1 :: Env -> Parser [FieldInfo]-record1 env- = do { reservedOp "{"- ; args1 <- many (ftype env << reservedOp ",")- ; fld <- field1 env- ; args2 <- many (reservedOp "," >> ftype env)- ; reservedOp "}"- ; return (map expand args1 ++ [fld] ++ map expand args2)- } <?> "Pads newtype record"- where- expand fty = (Nothing, fty, Nothing)--field1 :: Env -> Parser FieldInfo-field1 env- = do { id <- lower; reservedOp "::"; ty <- ptype env- ; predM <- optionMaybe predic- ; return (Just id, (NotStrict,ty), predM)- }------------------------------------------------------------------------------------ * HASKELL IN PADS DECLARATIONS--expression :: Parser Exp-expression = haskellExp- <|> literal--haskellExp :: Parser Exp-haskellExp = do { reservedOp "<|"- ; haskellParseExpTill "|>"- }- <?> "Pads Haskell expression"---haskellParseExp :: String -> Parser Exp-haskellParseExp str = case LHM.parseExp str of- Left err -> parserZero- Right expTH -> return expTH--haskellParseExpTill :: String -> Parser Exp-haskellParseExpTill op = do { str <- manyTill anyChar (reservedOp op)- ; haskellParseExp str- }--haskellParsePat :: String -> Parser Pat-haskellParsePat str = case LHM.parsePat str of- Left err -> parserZero- Right patTH -> return patTH--haskellParsePatTill :: String -> Parser Pat-haskellParsePatTill op = do { str <- manyTill anyChar (reservedOp op)- ; haskellParsePat str- }---literal :: Parser Exp-literal = fmap (LitE . CharL) (try charLiteral)- <|> reLiteral- <|> fmap (LitE . StringL) stringLiteral- <|> fmap (LitE . IntegerL) (try integer)- <|> fmap (VarE . mkName . qName) qualLower- <|> fmap (ConE . mkName . qName) qualUpper- <?> "Pads literal"--reLiteral :: Parser Exp-reLiteral = do { reservedOp reMark- ; str <- manyTill anyChar (reservedOp reMark)- ; return (ConE (mkName "RE") `AppE` LitE (StringL str))- }-reMark = "'"--literalPat :: Parser Pat-literalPat = fmap (LitP . CharL) (try charLiteral)- <|> reLiteralPat- <|> fmap (LitP . StringL) stringLiteral- <|> fmap (LitP . IntegerL) (try integer)- <|> fmap (VarP . mkName . qName) qualLower- <|> fmap (flip ConP [] . mkName . qName) qualUpper- <?> "Pads literal"--reLiteralPat :: Parser Pat-reLiteralPat = do { reservedOp reMark- ; str <- manyTill anyChar (reservedOp reMark)- ; return (ConP (mkName "RE") [LitP (StringL str)])- }--qualUpper, qualLower :: Parser QString-qualUpper = try (upper `sepBy1` reservedOp ".")-qualLower = try $ do { prefix <- many (upper << reservedOp ".")- ; final <- lower- ; return (prefix ++ [final])- }--upper :: Parser String-upper = try $ do { id <- identifier- ; guard $ isUpper (head id)- ; return id}--lower :: Parser String-lower = try $ do { id <- identifier- ; guard $ isLower (head id)- ; return id}--tyvar env = try $ do { v <- lower- ; guard (v `elem` env)- ; return v }------------------------------------------------------------------------------------ * LEXER--p << q = do {x<-p;q;return x}---lexer :: PT.TokenParser ()-lexer = PT.makeTokenParser (haskellStyle- { reservedOpNames = ["=", "=>", "{", "}", "::", "<|", "|>", "|", reMark, "." ],- reservedNames = ["data", "type", "newtype", "old", "existing", "deriving",- "using", "where", "terminator", "length", "of", "from",- "case", "constrain", "obtain", "partition","value" ]})--whiteSpace = PT.whiteSpace lexer-identifier = PT.identifier lexer-operator = PT.operator lexer-reserved = PT.reserved lexer-reservedOp = PT.reservedOp lexer-charLiteral = PT.charLiteral lexer-stringLiteral = PT.stringLiteral lexer-integer = PT.integer lexer-commaSep1 = PT.commaSep1 lexer-parens = PT.parens lexer-braces = PT.braces lexer-brackets = PT.brackets lexer
@@ -1,173 +0,0 @@-{-# LANGUAGE NamedFieldPuns,RecordWildCards #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Pretty- Description : Pretty printing utilities for Pads types- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Pretty where-import Data.Char (isPrint, ord)-import qualified Data.Map as M-import qualified Language.Haskell.TH as TH--import Text.PrettyPrint.Mainland as PP-import Text.PrettyPrint.Mainland.Class-import Language.Pads.Syntax-import qualified Language.Pads.Parser as P-import Language.Pads.RegExp---instance Pretty PadsDecl where- ppr (PadsDeclType con vars pat padsty) = text "type" <+> (ppr_decl_lhs con vars pat) <+> text "=" <+> ppr padsty- ppr (PadsDeclData con vars pat padsrhs cons) = text "data" <+> (ppr_decl_lhs con vars pat) <+> text "="- <+> ppr padsrhs <> ppr_derives cons- ppr (PadsDeclNew con vars pat branchInfo cons) = text "newtype" <+> (ppr_decl_lhs con vars pat) <+> text "="- <+> ppr branchInfo <> ppr_derives cons--ppr_decl_lhs id args patOpt = text id <> ppr_args args <> ppr_optArgPat patOpt-ppr_derives cons = case cons of- [] -> empty- [l] -> space <> text (qName l)- ls -> space <> tuple (map (text . qName) cons)--ppr_args args = case args of [] -> empty ; _ -> space <> (spread (map text args))---instance Pretty PadsData where- ppr (PUnion branches) = ppr_branches branches- ppr (PSwitch exp patBranches) = text "case" <+> ppr exp <+> text "of" <+> ppr_patBranches patBranches--ppr_patBranches patBranches = enclosesep empty empty (text " |") (map ppr_patBranch patBranches)-ppr_patBranch (pat, branchInfo) = ppr pat <+> text "->" <+> ppr branchInfo-ppr_branches branches = enclosesep empty empty (text " |") (map ppr branches)--instance Pretty BranchInfo where- ppr (BRecord con fields predOpt) = text con <+> braces (commasep (map ppr_fieldInfo fields)) <> (ppr_optPred predOpt)- ppr (BConstr con constrArgs predOpt) = (ppr_conApp con constrArgs) <> (ppr_optPred predOpt)--ppr_conApp con constrArgs = case constrArgs of- [(NotStrict,arg)] | argIsCon con arg -> text con- otherwise -> text con <+> (spread (map ppr_constrArgApp constrArgs))---argIsCon con arg = case arg of- PExpression (TH.LitE (TH.StringL str)) -> con == str- otherwise -> False--ppr_fieldInfo (varOpt, constrArg, expOpt)- = (case varOpt of Nothing -> empty ; Just var -> (text var) <+> (text "::") <> space)- <> ppr_constrArg constrArg- <> ppr_optPred expOpt--ppr_constrArg (strict, padsTy) = ppr_strict strict <> ppr padsTy--ppr_constrArgApp (strict, padsTy)- | isAtomicTy padsTy = ppr_strict strict <> ppr padsTy- | otherwise = ppr_strict strict <> parens (ppr padsTy)--ppr_alpha padsTy- | isAtomicTy padsTy = ppr padsTy- | otherwise = parens (ppr padsTy)--ppr_strict IsStrict = text "!"-ppr_strict NotStrict = empty--isAtomicTy (PList _ _ _ ) = True-isAtomicTy (PTycon _ ) = True-isAtomicTy (PTyvar _ ) = True-isAtomicTy (PExpression _ ) = True-isAtomicTy (PTuple _ ) = True-isAtomicTy _ = False---instance Pretty PadsTy where- ppr (PConstrain pat ty exp) = text "constrain" <+> ppr pat <+> text "::" <+> ppr ty <+> text "where" <+> ppr exp- ppr (PTransform sty dty exp) = text "transform" <+> ppr sty <+> text "=>" <+> ppr dty <+> text "using" <+> ppr exp- ppr (PList itemTy sepTy termTy) = ppr_padsList itemTy sepTy termTy- ppr (PValue exp ty) = text "value" <+> ppr exp <+> text "::" <+> ppr ty- ppr (PApp argTys expArgOpt) = spread (map ppr_alpha argTys) <> ppr_opt expArgOpt- ppr (PTuple tys) = tuple (map ppr tys)- ppr (PExpression exp) = ppr exp- ppr (PTycon con) = text (qName con)- ppr (PTyvar var) = text var--instance Pretty TH.Pat where- ppr = text . TH.pprint--pprHpat pat = case pat of- TH.TupP p -> ppr pat- otherwise -> parens (ppr pat)--instance Pretty TH.Exp where- ppr = pprHexp--pprHexp exp = case exp of- TH.VarE name -> text(TH.pprint exp)- TH.ConE name -> text(TH.pprint exp)- TH.LitE lit -> text(TH.pprint exp)- TH.AppE (TH.ConE re) (TH.LitE (TH.StringL str)) | re==TH.mkName "RE"- -> text("'"++str++"'")- otherwise -> ppr_bird (text(TH.pprint exp))--ppr_bird s = (text "<|") <> s <> (text "|>")--instance Pretty TermCond where- ppr (LTerm ty) = text "terminator" <+> ppr ty- ppr (LLen exp) = text "length" <+> ppr exp---ppr_padsList itemTy sepTyOpt termTyOpt = brackets (ppr itemTy <> ppr_sep sepTyOpt) <> ppr_opt termTyOpt--ppr_opt opt = case opt of Nothing -> empty ; Just e -> (space <> ppr e)-ppr_optArgPat pat = case pat of Nothing -> empty; Just e -> (space <> pprHpat e)--ppr_optPred pred = case pred of Nothing -> empty; Just e -> (space <> text "where" <+> ppr e)--ppr_sep Nothing = empty-ppr_sep (Just sepTy) = text " |" <+> ppr sepTy-----{- Utilities for generated pretty printer for PADS types -}-seplines :: Doc -> [Doc] -> Doc-seplines s = folddoc (\hd tl -> hd <> s </> tl)--whitesep = sep-field_ppr field_name ppr = text field_name <+> equals <+> ppr-record_ppr str pprs = namedty_ppr str (recordbody_ppr pprs)-recordbody_ppr docs = braces (align (seplines comma docs))--tuple_ppr ds = parens (align (commasep ds))--maybe_ppr d = case d of- Nothing -> text "Nothing"- Just a -> ppr a---namedty_ppr str ph = hang 2 (text str <+/> ph)--namedtuple_ppr :: String -> [Doc] -> Doc-namedtuple_ppr name pprls = group $ hang 2 (text name <+/> (tuple_ppr pprls))---list_ppr ds = (text "[---" <//>- align (seplines comma ds ) <//>- text "]")----instance (Pretty a, Pretty b) => Pretty (M.Map a b) where--- ppr = map_ppr-map_ppr d = list_ppr (map ppr (M.toList d))--string_ppr :: String -> Doc-string_ppr = ppr---namedlist_ppr :: String -> [Doc] -> Doc-namedlist_ppr name pprls = group $ hang 2 (text name <+/> (list_ppr pprls))
@@ -1,67 +0,0 @@-{-|- Module : Language.Pads.Quote- Description : Quasiquoter- Copyright : (c) 2005-2011 AT&T- Kathleen Fisher <kfisher@research.att.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Quote- (pads, padsDerivation, pparseDecl, make_pads_declarations)- where--import Prelude hiding (exp, init)-import System.IO.Unsafe (unsafePerformIO)--import Language.Haskell.TH-import Language.Haskell.TH.Quote (QuasiQuoter(..))--import Language.Pads.CodeGen-import qualified Language.Pads.Parser as P---- | The PADS quasiquoter which can be invoked by e.g.:------ > [pads| type MyType = (Int, Int) |]-pads :: QuasiQuoter-pads = padsDerivation (const $ return [])---- | Same as /pads/, but parametrized by a higher order function which--- constructs a list of Haskell decls to splice into scope for each PADS--- metadata and data declaration. Namely the /type/, /newtype/, and /data/ PADS--- constructs get passed into /derivation/ as a template haskell declaration.------ PADS only supports quasiquotes in place of a Haskell declaration--- (expressions, patterns, and types produce errors).-padsDerivation :: Derivation -> QuasiQuoter-padsDerivation derivation = QuasiQuoter- pparseExp- (error "parse pattern")- (error "parse type")- (pparseDecl derivation)---- | Just the declaration parser for a PADS quasiquotation. Glues together--- 'P.parsePadsDecls' and 'make_pads_declarations', the parser and code--- generator.-pparseDecl :: Derivation -> String -> Q [Dec]-pparseDecl derivation input = do- loc <- location- let fileName = loc_filename loc- let (line,column) = loc_start loc- case P.parsePadsDecls fileName line column input of- Left err -> unsafePerformIO $ fail $ show err- Right x -> make_pads_declarations' derivation x---- | Just the declaration parser for a PADS quasiquotation. Glues together--- 'P.parsePadsDecls' and 'make_pads_declarations', the parser and code--- generator.-pparseExp :: String -> Q Exp-pparseExp input = do- loc <- location- let fileName = loc_filename loc- let (line,column) = loc_start loc- case P.parsePadsDecls fileName line column input of- Left err -> unsafePerformIO $ fail $ show err- Right x -> make_pads_asts x-
@@ -1,20 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-|- Module : Language.Pads.RegExp- Description : Pads regular expressions- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.RegExp where-import Data.Data---- | Regular expression support. PADS uses the regex-posix package.-data RE = RE String -- ^ A regular expression printed as its match- | REd String String -- ^ A regular expression printed as the second arg- deriving (Eq, Data, Typeable, Show)-
@@ -1,566 +0,0 @@-{-# LANGUAGE NamedFieldPuns, RecordWildCards, DeriveDataTypeable #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Source- Description : Host language representation of data input- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental--}--module Language.Pads.Source where--import qualified Data.ByteString as B -- abstraction for input data-import qualified Text.Regex.Posix as TRP-import Language.Pads.RegExp -- user-specified regular expressions-import Text.PrettyPrint.Mainland as PP-import Text.PrettyPrint.Mainland.Class--import Data.Int-import Data.Data-import Data.Word-import Data.Char-import Data.Bits (shiftR, shiftL, (.&.))-import qualified Data.ByteString.Char8 as Char8--type RawStream = B.ByteString -- This is the type that should be used in other files!!!--{-| Input source abstraction -}-data Source = Source- { current :: B.ByteString -- ^ The current input before EOR- , rest :: B.ByteString -- ^ The rest of the input after the next EOR- , loc :: Loc -- ^ The current location 'Loc' in the input- , bit :: Int -- ^ Bit offset into the current input being parsed- , disc :: RecordDiscipline -- ^ The record discipline of this input source- , eorAtEOF :: Bool -- ^ Relevant for seperator-based record disciplines: Single, Multi- -- Set when current record is last record and separtor appeared at end.- }---- | A record discipline specifies the manner by which pads should partition the--- input into records. Note that the record character gets consumed internally--- by the parsing monad.-data RecordDiscipline =- Single Word8 -- ^ Split input based on a single 8-bit unsigned integer (character)- | Multi B.ByteString -- ^ Split input based on more than one character- | Bytes Int -- ^ Split the input into records every 'Int' characters- | NoPartition -- ^ No partitioning of the input - all input data is in the 'current' field- | NoDiscipline -- ^ No discipline is currently installed; all input data is in 'rest' field---- | Record discipline for Unix newlines-newline = Single (chrToWord8 '\n')--- | Record discipline for Windows CRLF newlines-windows = Multi (B.pack (strToWord8s "\r\n"))--- | Record discipline for every n characters-bytes n = Bytes n--- | No record discipline-none = NoPartition--{-| Source location information. -}-data Loc = Loc- { recordNumber :: Int64 -- ^ Number of records parsed so far (i.e. record index)- , byteOffset :: Int64 -- ^ Total number of bytes parsed into the source input so far- } deriving (Typeable, Data,Eq, Ord, Show)---- | A span in the source input, covering a contiguous range of the 'Source'--- input. AFAIK there's no distinction between the states where @begin == end@--- and where @end == Nothing@.-data Span = Span- { begin :: Loc -- ^ Start location of the 'Span'- , end :: Maybe Loc -- ^ End location of the 'Span', inclusive- } deriving (Typeable, Data, Eq, Ord, Show)---- | Initial instance of a 'Loc'-zeroLoc = Loc {recordNumber = 0, byteOffset = 0}---- | A span starting at the beginning of the file and containing nothing.-zeroSpan = locToSpan zeroLoc---- | Parse the most significant bit in a byte first-zeroBit = 7---- | Increment how many records have been seen in the given 'Loc'-incRecordNumber :: Loc -> Loc-incRecordNumber Loc{recordNumber, ..} = Loc{ recordNumber = recordNumber+1- , byteOffset = 0}---- | Decrement how many records have been seen in the given 'Loc'-decLineNumber :: Loc -> Loc-decLineNumber Loc{recordNumber, ..} = Loc{recordNumber=recordNumber-1, byteOffset=0}---- | Increment the offset of the 'Loc' by one-incOffset :: Loc -> Loc-incOffset l@Loc{byteOffset} = l { byteOffset = byteOffset + 1 }---- | Increment the offset of the given 'Loc' by some number-incOffsetBy :: Loc -> Int -> Loc-incOffsetBy l@Loc{byteOffset} n = l { byteOffset = byteOffset + fromIntegral n }---- | Decrement the offset of the given 'Loc' by one-decOffset :: Loc -> Loc-decOffset l@Loc{byteOffset} = l { byteOffset = byteOffset - 1 }--getSrcLoc :: Source -> Loc-getSrcLoc = loc--getRecordDiscipline :: Source -> RecordDiscipline-getRecordDiscipline = disc------------------------------------------------------------------------------------- * Source Creation---- | An empty Source with reasonable defaults for everything.-emptySource = Source- { current = B.empty- , rest = B.empty- , loc = zeroLoc- , bit = zeroBit- , eorAtEOF = False- , disc = newline- }---- | Stuff the given 'String' into a 'Source' with a newline discipline by--- default (see 'padsSourceFromByteString')-padsSourceFromString :: String -> Source-padsSourceFromString str = padsSourceFromByteString (strToByteString str)---- | Stuff the given 'String' into a 'Source' with the given record discipline-padsSourceFromStringWithDisc :: RecordDiscipline -> String -> Source-padsSourceFromStringWithDisc d str = padsSourceFromByteStringWithDisc d (strToByteString str)---- | Read a 'Source' from disk-padsSourceFromFile :: FilePath -> IO Source-padsSourceFromFile file = do- bs <- B.readFile file- return (padsSourceFromByteString bs)---- | Read a 'Source' from disk using the given record discipline-padsSourceFromFileWithDisc :: RecordDiscipline -> FilePath -> IO Source-padsSourceFromFileWithDisc d file = do- bs <- B.readFile file- return (padsSourceFromByteStringWithDisc d bs)---- | Construct a 'Source' from the given 'ByteString', preparing the first--- record immediately.-padsSourceFromByteString :: B.ByteString -> Source-padsSourceFromByteString bs =- let rawSource = Source{ current = B.empty- , rest = bs- , loc = zeroLoc- , bit = zeroBit- , disc = newline- , eorAtEOF = False- }- in getNextRecord rawSource---- | Same as 'padsSourceFromByteString' but with a record discipline-padsSourceFromByteStringWithDisc :: RecordDiscipline -> B.ByteString -> Source-padsSourceFromByteStringWithDisc d bs =- let rawSource = Source{ current = B.empty- , rest = bs- , loc = zeroLoc- , bit = zeroBit- , disc = d- , eorAtEOF = False- }- in getNextRecord rawSource---- | Whether or not the 'Source' has consumed all available input-isEOF :: Source -> Bool-isEOF (s @ Source{current, rest, eorAtEOF, ..}) = B.null current && B.null rest && not eorAtEOF---- | Whether or not the 'Source' has consumed all input in the current record-isEOR :: Source -> Bool-isEOR = B.null . current------------------------------------------------------------------------------------ * Record Manipulating Functions-{- Called when current is empty to get the next record, where the disc field defines what constitutes a record.- NOOP when isEOF is already true. -}-getNextRecord :: Source -> Source-getNextRecord (s @ Source {current, rest, loc, bit, disc, eorAtEOF}) =- if isEOF s then s- else if eorAtEOF || B.null rest then- (Source {current = B.empty, rest = B.empty, loc = incRecordNumber loc, bit = zeroBit, disc, eorAtEOF = False})- else (Source {current = nextLine, rest=residual, loc = incRecordNumber loc, bit = zeroBit, disc, eorAtEOF = eorAtEOF'}) --TODO: is this bit positioning sound?- where (nextLine, residual, eorAtEOF') = breakUsingDisc rest disc--srcLineBegin :: Source -> (Maybe String, Source)-srcLineBegin s = (Nothing, s)--srcLineEnd :: Source -> (Maybe String, Source)-srcLineEnd s = if isEOF s- then (Just "Found EOF when looking for EOR", s)- else (Nothing, getNextRecord s)--{- External code should not set discipline to NoDiscipline; that is an internal state only to- mark state between two legal external disciplines. -}-setRecordDiscipline :: RecordDiscipline -> Source -> ((),Source)-setRecordDiscipline r s =- let s' = unputCurrentLine s- s'' = s'{disc = r}- in ((),getNextRecord s'')--{- Merge current record back on to rest according to current record discipline.- Resulting source will be in NoDiscipline state.- Noop if called at EOF.--}-unputCurrentLine :: Source -> Source-unputCurrentLine (s @ Source {current, rest, loc, disc, eorAtEOF}) =- if isEOF s then s- else case disc of- Single n -> let rest' = if B.null rest- then if eorAtEOF- then B.concat [current, B.singleton n]- else current- else B.concat [current, B.singleton n, rest]- loc' = if B.null current then loc else decLineNumber loc- in Source {current = B.empty, rest = rest', loc = loc', bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}- Multi br -> let rest' = if B.null rest- then if eorAtEOF- then B.concat [current, br]- else current- else B.concat [current, rest]- loc' = if B.null current then loc else decLineNumber loc- in Source {current = B.empty, rest = rest', loc = loc', bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}- Bytes n -> Source {current = B.empty, rest = B.append current rest, loc = decLineNumber loc, bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}- NoPartition -> Source {current = B.empty, rest = current, loc = decLineNumber loc, bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}- NoDiscipline -> s---breakUsingDisc :: B.ByteString -> RecordDiscipline -> (B.ByteString, B.ByteString, Bool)-breakUsingDisc bs rd = case rd of- Single n -> let (nextLine, raw_residual) = B.break (\c->c == n) bs- residual = B.drop 1 raw_residual- eorAtEOF = (B.null residual) && (not $ B.null raw_residual)- in (nextLine, residual, eorAtEOF)- Multi s -> let (nextLine, raw_residual) = B.breakSubstring s bs- residual = B.drop (B.length s) raw_residual- eorAtEOF = (B.null residual) && (not $ B.null raw_residual)- in (nextLine, residual, eorAtEOF)- Bytes n -> let (nextLine, residual) = B.splitAt n bs- in (nextLine, residual, False)- NoPartition -> (bs, B.empty, False)- NoDiscipline -> error "Pads Source: Attempt to partition source using internal discipline 'NoDiscipline'"------------------------------------------------------------------------------------ * Converting Sources to Strings----padsSourceToString :: Source -> String-padsSourceToString = (map word8ToChr) . B.unpack . padsSourceToByteString--padsSourceToByteString :: Source -> B.ByteString-padsSourceToByteString = rest . unputCurrentLine--drainSource :: Source -> (String, Source)-drainSource s = (padsSourceToString s, emptySource)--drainSourceNB :: Source -> (String, Source)-drainSourceNB (s @ Source{current,loc, ..}) =- let len = (B.length current) - (if bit == zeroBit then 0 else 1)- (bs, s') = takeBits (len * 8) s- in (map word8ToChr (numToWord8s bs []), emptySource)---{- XXX: Change call site to use no record discipline; then this call should just became an instance of drainSource -}-rawSource :: Source -> (B.ByteString, Source)-rawSource s = (padsSourceToByteString s, emptySource)--{- Return the rest of the current record as a string -}-restRec :: Source -> String-restRec = byteStringToStr . current------------------------------------------------------------------------------------ * Operations within a single record-head :: Source -> Char-head = word8ToChr . headOrZero . current--headOrZero s = if B.null s then chrToWord8 '\0' else B.head s--peekHeadM :: Source -> (Maybe Char, Source)-peekHeadM (s @ Source{current,loc, ..}) =- if B.null current then (Nothing, s) else (Just (Language.Pads.Source.head s), s)--takeHead :: Source -> (Char, Source)-takeHead (s @ Source{current,loc, ..}) =- (word8ToChr $ B.head current, s{current = B.tail current, loc = incOffset loc})--partitionBS :: B.ByteString -> Int -> Int -> (B.ByteString, B.ByteString, Bool)-partitionBS bS bitIndex bits =- let part b bs = if bs > b + 1 then 1 + part zeroBit (bs - (b + 1)) else 1- byteAlign = (bits - (bitIndex + 1)) `mod` 8 == 0- withinByte = bits <= bitIndex + 1- hd = B.take (part bitIndex bits) bS- tl = B.drop (B.length hd - if not byteAlign then 1 else 0) bS- in (hd, tl, withinByte || not byteAlign)--accumulate :: Integral a => a -> (a, Int) -> (a, Int)-accumulate byte (num, pow) = ((byte * (256 ^ pow)) + num, pow + 1)--takeBits8 :: Int -> Source -> (Word8, Source)-takeBits8 b (s @ Source{current,loc,bit, ..}) =- let (hd, tl, partial) = partitionBS current bit b- bS = map (\x -> fromIntegral x :: Word16) (B.unpack $ B.take 2 hd)- bytes = fst $ foldr accumulate (0,0) bS- mask = (2 ^ b) - 1- bits = mask .&. shiftR bytes ((B.length hd * 8) - b - (zeroBit - bit))- in (fromIntegral bits, s{current = tl,- loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),- bit = (zeroBit - (((zeroBit - bit) + b) `mod` 8))})--takeBits16 :: Int -> Source -> (Word16, Source)-takeBits16 b (s @ Source{current,loc,bit, ..}) =- let (hd, tl, partial) = partitionBS current bit b- bS = map (\x -> fromIntegral x :: Word32) (B.unpack $ B.take 3 hd)- bytes = fst $ foldr accumulate (0,0) bS- mask = (2 ^ b) - 1- bits = mask .&. shiftR bytes ((B.length hd * 8) - b - (zeroBit - bit))- in (fromIntegral bits, s{current = tl,- loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),- bit = (zeroBit - (((zeroBit - bit) + b) `mod` 8))})--takeBits32 :: Int -> Source -> (Word32, Source)-takeBits32 b (s @ Source{current,loc,bit, ..}) =- let (hd, tl, partial) = partitionBS current bit b- bS = map (\x -> fromIntegral x :: Word64) (B.unpack $ B.take 5 hd)- bytes = fst $ foldr accumulate (0,0) bS- mask = (2 ^ b) - 1- bits = mask .&. shiftR bytes ((B.length hd * 8) - b - (zeroBit - bit))- in (fromIntegral bits, s{current = tl,- loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),- bit = zeroBit - (((zeroBit - bit) + b) `mod` 8)})--takeBits64 :: Int -> Source -> (Word64, Source)-takeBits64 b s = let (bits, s') = takeBits b s- in (fromIntegral bits, s')--tobinary :: Integer -> Integer-tobinary x- | (div x 2) == 0 = x- | otherwise = (mod x 2) + (10 * (tobinary $ div x 2))--takeBits :: Int -> Source -> (Integer, Source)-takeBits b (s @ Source{current,loc,bit, ..}) =- let (hd, tl, partial) = partitionBS current bit b- bS = map fromIntegral (B.unpack hd)- bytes = fst $ foldr accumulate (0,0) bS- mask = (2 ^ b) - 1- shiftAmt = max 0 ((B.length hd * 8) - b - (zeroBit - bit))- bits = mask .&. shiftR bytes shiftAmt- in (bits, s{current = tl,- loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),- bit = zeroBit - (((zeroBit - bit) + b) `mod` 8)})--takeHeadM :: Source -> (Maybe Char, Source)-takeHeadM (s @ Source{current,loc, ..}) =- if B.null current then (Nothing, s)- else (Just $ word8ToChr $ B.head current, s{current = B.tail current, loc = incOffset loc})---- | If the front of the current source input matches the given string then--- remove it and return the modified source. Otherwise return the original--- source and a boolean flag indicating that we failed to take the given string--- off the front of the source input.-takeHeadStr :: String -> Source -> (Bool, Source)-takeHeadStr str s =- let pstr = strToByteString str- in if B.isPrefixOf pstr (current s)- then let (res,source) = Language.Pads.Source.take (B.length pstr) s- in (True, source)- else (False, s)---matchString :: String -> Source -> Maybe(String, Source)-matchString str s =- let pstr = strToByteString str- in if B.isPrefixOf pstr (current s)- then let (res,source) = Language.Pads.Source.take (B.length pstr) s- in Just(str, source)- else Nothing---breakSubstring :: B.ByteString -- ^ String to search for- -> B.ByteString -- ^ String to search in- -> (B.ByteString,B.ByteString) -- ^ Head and tail of string broken at substring-breakSubstring pat src = search 0 src- where- -- STRICT2(search)- search :: Int -> B.ByteString -> (B.ByteString, B.ByteString)- search a b | a `seq` b `seq` False = undefined- search n s- | B.null s = (src,B.empty) -- not found- | pat `B.isPrefixOf` s = (B.take n src,s)- | otherwise = search (n+1) (B.tail s)--{-|- Scan the current source input until we find the given string:- - If we don't find the string return Nothing and leave source unmodified- - If we return (Maybe []), then we found the string at the beginning of the- source and removed it.- - If we return (Maybe junk), then we found the string somewhere after the- first character in the source and we consumed / removed (junk:str).--}-scanStr :: String -> Source -> (Maybe String, Source)-scanStr str (s @ Source{current,loc, ..}) =- let pat = strToByteString str- (before,after) = breakSubstring pat current- in if B.null after then (Nothing, s)- else let len = B.length pat- in (Just (byteStringToStr before),- s{current = B.drop len after, loc = incOffsetBy loc len})---scanString :: String -> Source -> Maybe (String, Source)-scanString str (s @ Source{current,loc, ..}) =- let pat = strToByteString str- (before,after) = breakSubstring pat current- in if B.null after then Nothing- else let len = B.length pat- in Just (byteStringToStr before, s{current= B.drop len after, loc = incOffsetBy loc len})--satisfyNB :: (Char -> Bool) -> Source -> (String, Source)-satisfyNB p s =- let (c, s') = takeBits8 8 s- c' = word8ToChr c- in if p c'- then (c' : (fst $ satisfyNB p s'), snd $ satisfyNB p s')- else ([], s)--takeBytes :: Int -> Source -> (B.ByteString, Source)-takeBytes n (s @ Source{current,loc, ..}) =- let (head, tail) = B.splitAt n current- incOffset = B.length head- in (head, s{current= tail, loc = incOffsetBy loc incOffset})--takeBytesNB :: Int -> Source -> (B.ByteString, Source)-takeBytesNB n s =- let (bits, s') = takeBits (n * 8) s- numToBS x = B.pack $ numToWord8s x []- in (numToBS bits, s')--numToWord8s :: Integral a => a -> [Word8] -> [Word8]-numToWord8s x accum- | x < 256 = fromIntegral x : accum- | otherwise = numToWord8s (x `div` 256) (fromIntegral (x `mod` 256) : accum)--take :: Int -> Source -> (String, Source)-take n s = let (bs, s') = takeBytes n s- in (byteStringToStr bs, s')---- | Match the beginning of the source input with a regex, returning a tuple of--- the matched string and the modified source with that string removed.-regexMatch :: RE -> Source -> (Maybe String, Source)-regexMatch (RE re_str_raw) (s @ Source{current,loc,..}) =- let (before, match, after) = current TRP.=~ (strToByteString('^' : re_str_raw))- in if not (B.null before) then (Nothing, s) -- only looking for matches at the beginning of the string- else (Just (byteStringToStr match), s{current=after, loc=incOffsetBy loc (fromIntegral (B.length match))})-regexMatch (REd re_str_raw def ) s = regexMatch (RE re_str_raw) s---- | Find the first match of a regex in the source input, returning the contents--- of the source input *before* the match.--- * If there's no match return Nothing and leave the source unmodified.--- * If there's a match, return the string before the match and remove *just*--- the string before from the source input.-regexStop :: RE -> Source -> (Maybe String, Source)-regexStop (RE re_str_raw) (s @ Source{current,loc,..}) =- let packed = strToByteString re_str_raw- (before, match, after) = current TRP.=~ packed -- Is there a way to test this result matches w/o duplicating match?- isMatch = current TRP.=~ packed- in if not isMatch- then (Nothing, s) -- match failed, return input unchanged- else (Just (byteStringToStr before),- s{current= B.append match after,loc=incOffsetBy loc (fromIntegral (B.length before))})---- | See 'regexStop'-regexStop (REd re_str_raw def) s = regexStop (RE re_str_raw) s---- | Remove and return the longest prefix of the source input satisfying the--- given predicate.-span p (s @ Source{current,loc,..}) =- let (head, tail) = B.span p current- incOffset = B.length head- in (B.unpack head, s{current=tail, loc = incOffsetBy loc incOffset})---- | Same as 'span' but for predicates over type 'Char'.-whileS :: (Char -> Bool) -> Source -> Maybe (String,Source)-whileS p (s @ Source{current,loc,..}) =- let (head, tail) = B.span (p . word8ToChr) current- incOffset = B.length head- in Just (byteStringToStr head, s{current=tail, loc=incOffsetBy loc incOffset})---- | Remove the first byte of the input source.-tail (s @ Source{current,loc,..}) =- (s{current=B.tail current,loc=incOffset loc})---- | Scan the input source until we find the given character. If we don't find--- the character indicate as such with the boolean (False) and remove all source--- input from the current record. If we do find the character, return True and--- consume input up to and including the matched character. The 'Span' in the--- returned tuple indicates the region in the input that got scanned and removed--- by this function (whether or not we failed to find the character).-scanTo :: Char -> Source -> (Bool, Source, Span)-scanTo chr (src @ Source{current,loc, ..}) =- let begin = getSrcLoc src- (skipped, residual) = B.break (\c->c== (chrToWord8 chr)) current- (found,remaining,incAmount) =- if B.null residual then -- Reached EOR w/o finding chr- (False, residual, B.length skipped)- else (True, B.tail residual, (B.length skipped) + 1)- newLoc = incOffsetBy loc incAmount- endErrLoc = incOffsetBy loc (B.length skipped)- in (found,- src {current = remaining, loc=newLoc},- Span {begin, end=Just endErrLoc})---lift :: (String -> [(a, String)]) -> (Source -> (Maybe a, Source))-lift f s = case f (byteStringToStr $ current s) of- [] -> (Nothing, s)- (x,residual):rest -> (Just x, s{current= (strToByteString residual)})--{- Helper routines -}--eqCurrent :: Source -> Source -> Bool-eqCurrent s s'= current s == current s'--chrToWord8 :: Char -> Word8-chrToWord8 c = toEnum $ fromEnum c--strToWord8s :: String -> [Word8]-strToWord8s = map chrToWord8--word8ToChr :: Word8 -> Char-word8ToChr = toEnum . fromEnum--word8sToStr :: [Word8] -> String-word8sToStr = map word8ToChr--byteStringToStr :: B.ByteString -> String-byteStringToStr = word8sToStr . B.unpack--strToByteString :: String -> B.ByteString---strToByteString = B.pack . strToWord8s-strToByteString = Char8.pack----locToSpan :: Loc -> Span-locToSpan loc = Span { begin = loc, end = Nothing }--locsToSpan :: Loc -> Loc -> Span-locsToSpan b e = Span {begin = b, end = Just e}------------------------------------------------------------------------------------ * Pretty print sources-instance Pretty Source where- ppr (Source{current, rest, ..}) = text "Current:" <+> text (show current)--instance Pretty Loc where- ppr (Loc{recordNumber,byteOffset}) = text "Line:" <+> ppr recordNumber <> text ", Offset:" <+> ppr byteOffset--instance Pretty Span where- ppr (Span{begin,end}) = case end of- Nothing -> ppr begin- Just end_loc -> text "from:" <+> ppr begin <+> text "to:" <+> ppr end_loc
@@ -1,191 +0,0 @@-{-# LANGUAGE DeriveDataTypeable,DeriveLift, DeriveAnyClass, DeriveGeneric #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.Syntax- Description : The concrete syntax of Pads in Haskell- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental-- Haskell data types, instances, and helper functions over these types for the- syntax of Pads.---}-module Language.Pads.Syntax where--import Data.Generics (Data(..), Typeable(..))-import Language.Haskell.TH-import Language.Haskell.TH.Lift (Lift(..))-import GHC.Generics (Generic(..))--instance Lift Pat-instance Lift Exp---- | AST form of a pads declaration with four flavors.-data PadsDecl- -- | A pads type declaration e.g.:- --- -- > [pads| type Foo x y z (foo :: Int) = (x, y, z, foo) |]- = PadsDeclType String [String] (Maybe Pat) PadsTy-- -- | A pads data declaration e.g.:- --- -- > [pads| data Foo x y z (foo :: Int) = Foo (x, y, z, foo) deriving (Eq, Ord, Show) |]- | PadsDeclData String [String] (Maybe Pat) PadsData [QString]-- -- | A pads newtype declaration e.g.:- --- -- > [pads| newtype Foo x y z (foo :: Int) = Foo (x, y, z, foo) deriving (Eq, Ord, Show) |]- | PadsDeclNew String [String] (Maybe Pat) BranchInfo [QString]-- -- | A pads declaration for obtaining one type after parsing it from another, e.g.:- --- -- > [pads| obtain Foo x y z from Int using <|(fncn,inverse)|> |]- | PadsDeclObtain String [String] PadsTy Exp- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | AST form of a pads type, as notably used to the right hand side of an--- equals sign in a @'PadsDecl'@ pads declaration.-data PadsTy- -- | AST form of "constrain @'Pat'@ :: @'PadsTy'@ where @'Exp'@" e.g.:- --- -- > [pads| constrain x :: Digit where <|x `mod` 2|> == 0|> |]- = PConstrain Pat PadsTy Exp-- -- | AST form of "transform @'PadsTy'@ => @'PadsTy'@ using @'Exp'@" e.g.:- --- -- > [pads| transform StringFW 1 => Char using <|(head, list1)|> |]- | PTransform PadsTy PadsTy Exp-- -- | AST form of a list of some @'PadsTy'@ type, comes with two optional attributes e.g.:- -- "[ @'PadsTy'@ | @'PadsTy'@ ] terminator @'TermCond'@"- --- -- The following @'PadsTy'@ describes a comma-separated list of integers- -- terminated by the EOF symbol:- --- -- > [pads| [Int | ','] terminator EOF |]- | PList PadsTy (Maybe PadsTy) (Maybe TermCond)-- -- | AST form of a partitioned type "partition @'PadsTy'@ using @'Exp'@" e.g.:- --- -- > [pads| partition Entries using <| bytes 6 |> |]- --- -- A partitioned type allows for parser extensions to make use of the state of- -- the PADS parser in deciding how to divide up (partition) the input.- | PPartition PadsTy Exp-- -- | AST form of a value constructor "value @'Exp'@ :: @'PadsTy'@" e.g.:- --- -- > [pads| data Foo = Foo { x :: Int, xIsEven = value <| even x |> :: Bool } |]- --- -- This allows you to do the opposite of what @'BConstr'@ does: bring names into- -- scope which get stored in the output of the parser (rather than having them- -- disappear after the parser finishes.- | PValue Exp PadsTy-- -- | A pads type application like "@'PadsTy'@ @'PadsTy'@ @'PadsTy'@ ... @'Exp'@" e.g.- --- -- > [pads| data Foo = Foo { x :: Int, Bar x <| x + 1 |> |]- | PApp [PadsTy] (Maybe Exp)-- -- | AST form of a pads tuple "( @'PadsTy@', @'PadsTy@', ... )" e.g.- --- -- > [pads| (Int, "+", Int) |]- | PTuple [PadsTy]-- -- | An arbitrary Haskell expression as used in a @'PApp'@ pads type application- -- and in a @'PSwitch'@ pads switch/case type.- | PExpression Exp-- -- | Pads type constructor with a qualified name- | PTycon QString-- -- | Pads type variable with a name- | PTyvar String- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | Parser terminator condition-data TermCond- -- | Lexical terminator type: any @'PadsTy'@ signaling termination- = LTerm PadsTy-- -- | Lexical length: arbitrary Haskell @'Exp@'- | LLen Exp- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | Right-hand side of a pads data type declaration-data PadsData- -- | A pads union data type declaration.- -- Syntax: "@'BranchInfo'@ | @'BranchInfo'@ | ..."- = PUnion [BranchInfo]-- -- | A pads switch-case 'statement'.- --- -- Syntax:- --- -- @- -- case 'Exp' of- -- 'Pat' -> 'BranchInfo'- -- | 'Pat' -> 'BranchInfo'- -- ...- -- @- --- -- > [pads| case <| tag + 1 |> of- -- > 2 -> Foo- -- > | 3 -> Bar- -- > |]- | PSwitch Exp [(Pat,BranchInfo)]- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | An individual branch of some pads data type, either defining a Haskell record--- parser or a Haskell constructor parser.-data BranchInfo- -- | Branch record with a constructor name, list of record fields, and maybe a boolean 'where' clause.- --- -- Syntax: @'String'@ { @'FieldInfo'@, @'FieldInfo'@, ... } where @'Exp@'- --- -- > [pads| Foo { x :: Int, y :: Char } where <| x == ord y |>- = BRecord String [FieldInfo] (Maybe Exp)-- -- | Branch constructor with a constructor name, a list of argument types, and maybe a boolean 'where' clause:- --- -- Syntax: @'String'@ @'ConstrArg'@ @'ConstrArg'@ ... where @'Exp@'- --- -- > [pads| Foo (x :: Int) (y :: Char) where <| x == ord y |>- --- -- Note that this lets you bring variables into scope during parsing (`x` and- -- `y` in the above) *without* saving them into the parse result, effectively- -- making them operate as temporary variables that can be referenced by the- -- Haskell predicates.- | BConstr String [ConstrArg] (Maybe Exp)- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | Individual field of a pads record, "@'String'@ :: @'ConstrArg'@ where @'Exp'@"-type FieldInfo = (Maybe String, ConstrArg, Maybe Exp)-type ConstrArg = (PadsStrict, PadsTy)---- | A hold-over resulting from a deprecation moving from an older version of template-haskell.-data PadsStrict = IsStrict | NotStrict | Unpacked- deriving (Eq, Data, Typeable, Show, Lift, Generic)---- | Qualified names where ["Foo", "Bar"] means "Foo.Bar"-type QString = [String]---- | Whether or not a @'PadsTy'@ has an underlying Haskell representation-hasRep :: PadsTy -> Bool-hasRep (PExpression l) = False-hasRep (PTycon ["EOF"]) = False-hasRep (PTycon ["EOR"]) = False-hasRep (PTycon ["Void"]) = False-hasRep ty = True---- | > ["Foo", "Bar"] -> "Foo.Bar"-qName :: QString -> String-qName [n] = n-qName (n:ms) = n ++ "." ++ qName ms---
@@ -1,164 +0,0 @@-{-# LANGUAGE TemplateHaskell, MagicHash #-}-{-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_HADDOCK prune #-}-{-|- Module : Language.Pads.TH- Description : Template Haskell utilities- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.TH where--import Language.Haskell.TH as TH-import Language.Haskell.TH.Syntax-import Control.Monad-import Data.Char-import GHC.Exts--typeAnnotate :: Maybe TH.Pat -> Maybe (TH.Pat, TH.Type)-typeAnnotate Nothing = Nothing-typeAnnotate (Just pat) = Just (pat, patToTy pat)--mergeMaybe :: Maybe a -> Maybe b -> Maybe (a,b)-mergeMaybe m1 m2 = case (m1,m2) of- (Nothing, Nothing) -> Nothing- (Just d1, Just d2) -> Just (d1,d2)- _ -> error "mergeMaybe given two maybes in different states."--mapFstChar :: (Char -> Char) -> String -> String-mapFstChar _ [] = []-mapFstChar f (c:cs) = f c : cs--strToUpper, strToLower :: String -> String-strToUpper = mapFstChar toUpper-strToLower = mapFstChar toLower--applyE :: [Exp] -> Exp-applyE ts = foldl1 AppE ts--applyT :: [Type] -> Type-applyT ts = foldl1 AppT ts--abstractT :: Type -> [Type] -> Type-abstractT t ts = foldr arrow t ts- where- t1 `arrow` t2 = (ArrowT `AppT` t1) `AppT` t2--arrowTy :: Type -> Type -> Type-arrowTy ty1 ty2 = (ArrowT `AppT` ty1) `AppT` ty2---mkListT, mkTupleT :: [Type] -> Type-mkListT ts = foldl AppT ListT ts-mkTupleT ts = foldl AppT (TupleT (length ts)) ts--listTH, tupleTH :: [Name] -> Q Exp-listTH xs = return (ListE (map VarE xs))-tupleTH xs = return (TupE (map VarE xs))----tupleTyToListofTys :: Type -> (Int,[Type])---- for tuples encoded as AppT (,) (AppT a b)-tupleTyToListofTys (AppT (TupleT n) ty0) = (n, collect ty0)- where- collect ty = case ty of- AppT ty' tys' -> ty' : collect tys'- _ -> [ty]---- for tuples encoded as AppT (AppT (,) a) b-tupleTyToListofTys ty0 = collect ty0 []- where- collect ty acc = case ty of- TupleT n -> (n, acc)- AppT tys ty' -> collect tys (ty':acc)- _ -> error "typeleTyToListofTys: unexpected type"--genPE :: Name -> (Exp,Pat)-genPE name = (VarE name, VarP name)--genPEQ :: Name -> (Q Exp, Q Pat)-genPEQ name = (return (VarE name), return (VarP name))--doGenPE :: String -> Q (Exp,Pat)-doGenPE str = do {- ; name <- newName str- ; return (VarE name, VarP name)- }--doGenPEs :: Int -> String -> Q([TH.Exp], [TH.Pat])-doGenPEs n str = do- { varpats <- replicateM n (doGenPE str)- ; return (unzip varpats)- }--{- XXX: need to add location information so can report location of error messages. -}-patToTy :: TH.Pat -> TH.Type-patToTy pat = case pat of- LitP l -> litToTy l- VarP n -> error ("Variable "++ (showName n) ++ " needs a type annotation.")- TupP pats -> mkTupleT (map patToTy pats)- InfixP _ n _ -> error ("Infix constructor "++ (showName n) ++ " application needs a type annotation.")- TildeP p -> patToTy p- BangP p -> patToTy p- AsP _ p -> patToTy p- WildP -> error "Wild card patterns are not supported in PADS declarations."- {- I think this is the correct represtentation of a line type. -}- RecP name _fieldPats -> ConT name- ListP pats -> mkListT (map patToTy pats)- SigP _ ty -> ty- ParensP pat' -> patToTy pat'- _ -> error ("patToTy: unexpected pat: " ++ show pat)--litToTy :: TH.Lit -> TH.Type-litToTy lit = ConT $ case lit of- CharL _ -> ''Char- StringL _ -> ''String- IntegerL _ -> ''Integer- RationalL _ -> ''Rational- IntPrimL _ -> ''Integer- WordPrimL _ -> ''Integer- FloatPrimL _ -> ''Rational- DoublePrimL _ -> ''Rational- _ -> error ("litToTy: unexpected lit: " ++ show lit)--patToExp :: TH.Pat -> TH.Exp-patToExp pat = case pat of- LitP l -> LitE l- VarP n -> VarE n- TupP pats -> TupE (map patToExp pats)- InfixP p1 n p2 -> InfixE (Just (patToExp p1)) (VarE n) (Just (patToExp p2))- TildeP p -> patToExp p- BangP p -> patToExp p- AsP n _ -> VarE n- WildP -> error "Wild card patterns are not supported in PADS \- \ declarations. Can't convert to expression"-- {- I think this is the correct represtentation of a line type. -}- RecP name fieldPats -> RecConE name (map fieldPatToExp fieldPats)- ListP pats -> ListE (map patToExp pats)- SigP p _ty -> patToExp p- ParensP p -> patToExp p- _ -> error ("patToExp: unexpected pat: " ++ show pat)--fieldPatToExp :: (a,Pat) -> (a,Exp)-fieldPatToExp (n,p) = (n, patToExp p)--boolToExpE :: Bool -> Exp-boolToExpE True = ConE 'True-boolToExpE False = ConE 'False---- generate globally scoped unique variables as suggested in https://ghc.haskell.org/trac/ghc/ticket/5398-mangleName :: Name -> Name-mangleName name@(Name occ fl) = case fl of- NameU (I# u) -> Name (mangle_occ occ u) fl- _ -> name- where- mangle_occ :: OccName -> Int# -> OccName- mangle_occ occ' uniq = mkOccName (occString occ' ++ "_" ++ show (I# uniq))
@@ -1,33 +0,0 @@-{-# OPTIONS_HADDOCK prune, ignore-exports #-}-{-|- Module : Language.Pads.Testing- Description : Pads testing utilities- Copyright : (c) 2011- Kathleen Fisher <kathleen.fisher@gmail.com>- John Launchbury <john.launchbury@gmail.com>- License : MIT- Maintainer : Karl Cronburg <karl@cs.tufts.edu>- Stability : experimental---}-module Language.Pads.Testing (- module Test.HUnit,- mkTestCase,- mkFileTestCase,- mdToError,- mdFileToError- )- where--import Language.Pads.Padsc-import Test.HUnit hiding (test)--mdToError ((rep,md), residual) = (rep, getTotalErrors md, residual)-mkTestCase s expected seen = TestCase(assertEqual s expected (mdToError seen))--mdFileToError (rep,md) = (rep, getTotalErrors md)-mkFileTestCase s expected seen = TestCase(assertEqual s expected (mdFileToError seen))--getTotalErrors :: PadsMD md => md -> Int-getTotalErrors md = numErrors $ get_md_header md-
@@ -0,0 +1,71 @@+# pads-haskell+Massive amounts of useful data are stored and processed in ad hoc formats for+which common tools like parsers, printers, query engines and format converters+are not readily available. Pads/Haskell is a domain-specific language that+facilitates the generation of data processing tools for ad hoc formats.+Pads/Haskell includes features such as dependent, polymorphic and recursive+datatypes, which allow programmers to describe the syntax and semantics of ad+hoc data in a concise, easy-to-read notation. ++The pads haskell repository contains the code for the Haskell binding for PADS.+For more information about the project, see the pads website+(www.padsproj.org).++# Building++`pads-haskell` currently requires GHC 8.2.2 and stack resolver lts-11.3.++## Setup++To generate an appropriate [Stack][1] configuration file and install an+appropriate GHC tool chain:++```bash+$ stack solver # Updates stack.yaml if necessary+$ stack setup # Installs ghc in a sandbox for you+```++## Build++To build `pads-haskell`:++```bash+$ stack build+```++# Testing++To run the automated testing infrastructure:++```bash+$ stack test :examples --ghc-options="-ddump-splices"+# Followed by this if you want to see the dumped splice files:+$ find . -name *.dump-splices+```++To run individual tests do:++```bash+$ stack repl+λ> :l Examples.First+...+λ> test+Cases: 89 Tried: 89 Errors: 0 Failures: 0+Counts {cases = 89, tried = 89, errors = 0, failures = 0}+(0.11 secs, 0 bytes)+```++# Contributing and Development++In order to build and view the haddock documentation do the following:++```bash+stack haddock+firefox `find .stack-work -name index.html | grep "html/pads-haskell"`+```++Pull requests are strongly encouraged, though we're more likely to merge them in+a timely fashion if they either add small features to existing modules or are+new PADS descriptions to add to the `examples` directory.++[1]: https://www.stackage.org/
@@ -1,77 +0,0 @@-{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable- , MultiParamTypeClasses- , TypeSynonymInstances- , TemplateHaskell- , QuasiQuotes- , FlexibleInstances #-}-module Main where-import System.IO.Unsafe (unsafePerformIO)-import Data.Monoid-import Test.Framework-import Test.Framework.Providers.HUnit-import Test.Framework.Providers.QuickCheck2-import qualified Test.HUnit as H-import Test.HUnit ((@?=))-import Test.QuickCheck (Property, quickCheck, (==>))-import qualified Test.QuickCheck.Monadic as TQM-import Control.Monad.State.Lazy (liftIO)--import Language.Pads.Padsc-import Examples.Proc-import qualified Examples.First as First-import qualified Examples.AI as AI-import qualified Examples.Binary as Binary--procMaps fn =- let (MapsFile maps, maps_md) = unsafePerformIO $ parseFileWith mapsFile_parseM fn- in last maps- @?=- Region { start_addr = "ffffffffff600000"- , end_addr = "ffffffffff601000"- , perms = Permissions- { permRead = READ- , permWrite = NOWRITE- , permExec = EXEC- , permShare = PRIVATE- }- , offset = 0- , device = ("00", "00")- , inode = 0- , path = VSyscall- }--testFirst =- unsafePerformIO First.test- @?=- H.Counts (length First.tests) (length First.tests) 0 0--testAI = True ==> TQM.monadicIO $ do- r <- liftIO $ AI.result 1- TQM.assert $ r ==- [ AI.Entry- { AI.host = AI.Addr 207 136 97 49- , AI.identdID = AI.Missing- , AI.httpID = AI.Missing- , AI.time = read "1997-10-16 01:46:51 UTC"- , AI.request = AI.Request- { AI.method = AI.GET- , AI.url = "/turkey/amnty1.gif"- , AI.version = AI.Version {AI.major = 1, AI.minor = 0}- }- , AI.response = 200- , AI.contentLen = AI.ContentLength 3013- }- ]--testBinary =- unsafePerformIO Binary.test- @?=- H.Counts (length Binary.tests) (length Binary.tests) 0 0--main :: IO ()-main = defaultMainWithOpts- [ testCase "Examples.First" testFirst- , testProperty "Examples.AI" testAI- , testCase "proc maps file 0" (procMaps "Test/data/maps0")- ] mempty-
@@ -1,33 +0,0 @@-00400000-00422000 r-xp 00000000 fe:02 4968 /usr/bin/less-00622000-00623000 r--p 00022000 fe:02 4968 /usr/bin/less-00623000-00627000 rw-p 00023000 fe:02 4968 /usr/bin/less-00627000-0062b000 rw-p 00000000 00:00 0 -00aa0000-00ac1000 rw-p 00000000 00:00 0 [heap]-7f1ae9999000-7f1ae99b2000 r-xp 00000000 fe:02 93235 /usr/lib/libpthread-2.25.so-7f1ae99b2000-7f1ae9bb1000 ---p 00019000 fe:02 93235 /usr/lib/libpthread-2.25.so-7f1ae9bb1000-7f1ae9bb2000 r--p 00018000 fe:02 93235 /usr/lib/libpthread-2.25.so-7f1ae9bb2000-7f1ae9bb3000 rw-p 00019000 fe:02 93235 /usr/lib/libpthread-2.25.so-7f1ae9bb3000-7f1ae9bb7000 rw-p 00000000 00:00 0 -7f1ae9bb7000-7f1ae9d52000 r-xp 00000000 fe:02 93077 /usr/lib/libc-2.25.so-7f1ae9d52000-7f1ae9f51000 ---p 0019b000 fe:02 93077 /usr/lib/libc-2.25.so-7f1ae9f51000-7f1ae9f55000 r--p 0019a000 fe:02 93077 /usr/lib/libc-2.25.so-7f1ae9f55000-7f1ae9f57000 rw-p 0019e000 fe:02 93077 /usr/lib/libc-2.25.so-7f1ae9f57000-7f1ae9f5b000 rw-p 00000000 00:00 0 -7f1ae9f5b000-7f1ae9fcd000 r-xp 00000000 fe:02 108084 /usr/lib/libpcre.so.1.2.8-7f1ae9fcd000-7f1aea1cc000 ---p 00072000 fe:02 108084 /usr/lib/libpcre.so.1.2.8-7f1aea1cc000-7f1aea1cd000 r--p 00071000 fe:02 108084 /usr/lib/libpcre.so.1.2.8-7f1aea1cd000-7f1aea1ce000 rw-p 00072000 fe:02 108084 /usr/lib/libpcre.so.1.2.8-7f1aea1ce000-7f1aea235000 r-xp 00000000 fe:02 106343 /usr/lib/libncursesw.so.6.0-7f1aea235000-7f1aea434000 ---p 00067000 fe:02 106343 /usr/lib/libncursesw.so.6.0-7f1aea434000-7f1aea438000 r--p 00066000 fe:02 106343 /usr/lib/libncursesw.so.6.0-7f1aea438000-7f1aea43a000 rw-p 0006a000 fe:02 106343 /usr/lib/libncursesw.so.6.0-7f1aea43a000-7f1aea45d000 r-xp 00000000 fe:02 93078 /usr/lib/ld-2.25.so-7f1aea490000-7f1aea629000 r--p 00000000 fe:02 96759 /usr/lib/locale/locale-archive-7f1aea629000-7f1aea62d000 rw-p 00000000 00:00 0 -7f1aea65c000-7f1aea65d000 r--p 00022000 fe:02 93078 /usr/lib/ld-2.25.so-7f1aea65d000-7f1aea65e000 rw-p 00023000 fe:02 93078 /usr/lib/ld-2.25.so-7f1aea65e000-7f1aea65f000 rw-p 00000000 00:00 0 -7fff3cc14000-7fff3cc35000 rw-p 00000000 00:00 0 [stack]-7fff3cc3a000-7fff3cc3c000 r--p 00000000 00:00 0 [vvar]-7fff3cc3c000-7fff3cc3e000 r-xp 00000000 00:00 0 [vdso]-ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
@@ -0,0 +1,91 @@+{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances #-}++-- :set -ddump-splices++module AI where+import Language.Pads.Padsc+import Language.Pads.GenPretty++import System.IO.Unsafe (unsafePerformIO)+++[pads|+ newtype AI = AI ([Line Entry] terminator EOF)++ data Entry = Entry+ { host :: Src,+ ' ', identdID :: ID,+ ' ', httpID :: ID,+ ' ', time :: TimeStamp,+ ' ', request :: Request,+ ' ', response :: Response,+ ' ', contentLen :: ContentLength }++ data Src = Addr+ { a :: IPInt, '.'+ , b :: IPInt, '.'+ , c :: IPInt, '.'+ , d :: IPInt+ }+ | Name Host+ --type IP_v4 = (IPInt, '.', IPInt, '.', IPInt, '.', IPInt)+ type IPInt = constrain i :: Int where <| 0 <= i && i < 256 |>+ type Host = StringC ' '++ data ID = Missing '-' | Id (StringC ' ')++++ type TimeStamp = ('[', Date, ']')+ type Date = DateFC <|("%d/%h/%Y:%H:%M:%S %z", ']')|>++ data Request = Request+ { '"', method :: Method,+ ' ', url :: StringC ' ',+ ' ', version :: Version where <| checkVersion method version |>, '"'+ }++ data Method = GET | PUT | POST | HEAD | DELETE+ | LINK | UNLINK -- obsolete after http 1.0+ data Version = Version {"HTTP/", major :: Int, '.', minor :: Int} -- add constriants on major and minor mode++ type Response = constrain r :: Int where <| 100 <= r && r < 600 |>++ data ContentLength = NotAvailable '-' | ContentLength Int+ |]++checkVersion :: Method -> Version -> Bool+checkVersion method version =+ case method of+ LINK -> major version == 1 && minor version == 0+ UNLINK -> major version == 1 && minor version == 0+ _ -> True++++mkPrettyInstance ''AI+mkPrettyInstance ''AI_md++ai_file = ai_big+ai_3000 = "examples/data/ai.3000"+ai_big = "examples/data/ai.big"++-- (ai_rep, ai_md) = let (AI rep, md) = unsafePerformIO $ parseFile ai_file in (rep,md)+(AI ai_rep, ai_md) = unsafePerformIO $ parseFileWith aI_parseM ai_file+++ai_file_length = Prelude.length ai_rep+ai_file_take n = Prelude.take n ai_rep+test = ai_file_take 20++printAI n = putStrLn(pretty 100 (ppr (ai_file_take n)))++result n = do+ { (AI rep, md) <- parseFile ai_file+ ; return (Prelude.take n rep)+ }
@@ -0,0 +1,32 @@+{-# LANGUAGE TypeFamilies+ , ScopedTypeVariables+ , DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances+ , FlexibleContexts+ , RecordWildCards+ , NamedFieldPuns+ , OverloadedStrings #-}++module Addrs where++import Language.Pads.Padsc+import Language.Pads.Testing+import System.IO.Unsafe (unsafePerformIO)++import qualified Data.ByteString as B+import qualified Language.Pads.Library.LittleEndian as LE+import qualified Language.Pads.Library.BigEndian as BE++test = [pads|+ newtype Addresses = Addresses ([Address])++ data Address = Address {num :: Int, ' ', street :: StringC '\n'}+|]++testbits = [pads|+ data SomeBits = SomeBits {x :: Bits8 9, y :: Bits8 4}+|]
@@ -0,0 +1,16 @@+module All where++import AI+import Binary+import DOS+import First+import HmmPlusOrig+import HPROF+import IntPair+import One+import Pnm+import Regression+import Small+import VCardInfinite+import VCard+
@@ -0,0 +1,81 @@+{-# LANGUAGE TypeFamilies+ , ScopedTypeVariables+ , DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances+ , FlexibleContexts+ , RecordWildCards+ , NamedFieldPuns #-}++module Arith where+import Language.Pads.Padsc+import qualified Language.Pads.Library.LittleEndian as LE+import qualified Language.Pads.Library.BigEndian as BE+-- import Data.Bits+import qualified Data.ByteString as B+import Data.Word+-- import Language.Pads.Testing+import System.IO.Unsafe (unsafePerformIO)++[pads|+ newtype Image = Image (partition (Header, '\n',+ Dimensions, '\n',+ [Pixel] terminator EOF) using none)++ type Header = StringC '\n'+ type Header2 = String++ data Dimensions = Dimensions {w :: Int, ' ', h :: Int}++ data Pixel = Pixel {+ a :: Bits16 9,+ b :: Bits8 5,+ c :: Bits8 5,+ d :: Bits8 5,+ pb_index :: Bits8 4,+ pr_index :: Bits8 4+ }+|]++nc = "data/arith_image"++(Image (header, dimensions, pixels), md) =+ unsafePerformIO $ parseFileWith image_parseM nc++-- test =+-- let p0 = pixels !! 0+-- p1 = pixels !! 100+-- p2 = pixels !! 328+-- p3 = pixels !! 897+-- p4 = pixels !! 1028+-- p5 = pixels !! 3205+-- p6 = pixels !! 5067+-- p7 = pixels !! 7345+-- p8 = pixels !! 9834+-- p9 = pixels !! (length pixels - 1)+-- ps = [p0,p1,p2,p3,p4,p5,p6,p7,p8,p9]+-- in (map a ps,+-- map b ps,+-- map c ps,+-- map d ps,+-- map pb_index ps,+-- map pr_index ps)++-- chars = do+-- (Image' (_, _, cs), md) <- parseFileWith image'_parseM nc+-- return cs+--+-- word8s = do+-- (Image'' (_, _, ws), md) <- parseFileWith image''_parseM nc+-- return ws++--f x = if x == 255 then (x :: Word8) else (x :: Word16)++-- bits = map (\x -> fromIntegral x :: Integer) pixels+-- (n, _) = foldr (\x z -> (x * (2 ^ snd z) + fst z, snd z + 1)) (0,0) bits++-- (EnumTypes codes, codes_md) =+-- unsafePerformIO $ parseFileWith enumTypes_parseM "data/enums.txt"
@@ -0,0 +1,74 @@+{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables #-}+module Binary where+import Language.Pads.Padsc+import Language.Pads.Library.LittleEndian as LE+import qualified Language.Pads.Library.BigEndian as BE+import qualified Language.Pads.Library.Native as Native+import Language.Pads.Testing+import System.IO.Unsafe (unsafePerformIO)++test = runTestTT $ TestList tests++tests = [TestLabel "Calls" call_test+ ,TestLabel "Calls" callNoRec_test+ ,TestLabel "BaseTypes" testRec_test]+++[pads| data Call = Call+ { onpa :: Int32, obase :: LE.Int32+ , dpna :: Int32, dbase :: Int32+ , con :: Int32+ , dur :: Int32 }++ type Calls = [Call | EOR] terminator EOF+ type CallsB = partition Calls using <| bytes 24 |>++ type CallsNoRec = [Call] terminator EOF+ type CallsNoRecInstall = partition CallsNoRec using none+|]++call_input_file = "data/calls10.b"+call_result :: (Calls, Calls_md) = unsafePerformIO $ parseFileWith callsB_parseM call_input_file+call_expect = ([Call {onpa = 221, obase = 2360199, dpna = 936, dbase = 3615299, con = 96977709, dur = 71},Call {onpa = 221, obase = 2360399, dpna = 855, dbase = 5445599, con = 96978527, dur = 126},Call {onpa = 221, obase = 2390199, dpna = 974, dbase = 4298199, con = 96980122, dur = 990},Call {onpa = 221, obase = 2390399, dpna = 855, dbase = 5404599, con = 96976885, dur = 35},Call {onpa = 222, obase = 2332099, dpna = 426, dbase = 6814599, con = 96977173, dur = 4850},Call {onpa = 222, obase = 2332099, dpna = -15, dbase = 9999999, con = 96978457, dur = 533},Call {onpa = 222, obase = 2340599, dpna = 855, dbase = 8442799, con = 96980047, dur = 8},Call {onpa = 222, obase = 2341299, dpna = 855, dbase = 7081599, con = 96979104, dur = 11},Call {onpa = 223, obase = 2340099, dpna = 855, dbase = 2484499, con = 96977739, dur = 564},Call {onpa = 223, obase = 2340199, dpna = -15, dbase = 9999999, con = 96979345, dur = 143}],0)+call_test = mkFileTestCase "Call" call_expect call_result++callNoRec_result = unsafePerformIO $ parseFileWith callsNoRecInstall_parseM call_input_file+callNoRec_test = mkFileTestCase "CallNoRec" call_expect callNoRec_result++binary_input_file = "data/binary"+word32sbh_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith BE.word32_parseM binary_input_file+word32sbh_expect = (2864434397,0 )++word32sbl_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith LE.word32_parseM binary_input_file+word32sbl_expect = (3721182122,0)++{- on a little endian machine -}+word32_result :: (Word32, Base_md) = unsafePerformIO $ parseFileWith Native.word32_parseM binary_input_file+word32_expect = (3721182122,0)+++int32sbh_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith BE.int32_parseM binary_input_file+int32sbh_expect = (-1430532899,0)++int32sbl_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith LE.int32_parseM binary_input_file+int32sbl_expect = (-573785174,0 )++{- on a little endian machine -}+int32_result :: (Int32, Base_md) = unsafePerformIO $ parseFileWith Native.int32_parseM binary_input_file+int32_expect = (-573785174,0 )+++[pads| data TestRec = TestRec+ { w8 :: Word8+ , i8 :: Int8+ , w16 :: Word16+ , i16 :: Int16+ , j16 :: Int16+ , w32 :: Word32+ , i32 :: Int32+ } |]++testRec_input_file = "data/binTest.b"+testRec_result :: (TestRec, TestRec_md) = unsafePerformIO $ parseFileWith testRec_parseM testRec_input_file+testRec_expect = (TestRec {w8 = 25, i8 = 23, w16 = 300, i16 = -400, j16 = 899, w32 = 9876, i32 = -98744},0)+testRec_test = mkFileTestCase "BinaryBaseTypes" testRec_expect testRec_result
@@ -0,0 +1,62 @@+{-# LANGUAGE TypeFamilies+ , ScopedTypeVariables+ , DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances+ , FlexibleContexts+ , RecordWildCards+ , NamedFieldPuns+ , OverloadedStrings #-}++module DFA where++import Language.Pads.Padsc+import Language.Pads.Testing+import Data.Word+++++[pads|+ -- s1 -- c --> s2+ -- s2 -- a --> s3+ -- s3 -- a --> s3+ -- s3 -- t --> s4++ data START = START {start::S1}++ data S1 = S1 {+ 'c',+ s2::S2 + }++ data S2 = S2 { 'a',+ s3 :: S3+ }++ data S3 = S3A { 'a', s3a::S3 } |+ S3T { 't', ss4::S4 }++ data S4 = S4 {s4::ACCEPT}++ data ACCEPT = ACCEPT ()++|]+++++testdfa parser str = + let + ((x, (y, z)), s) = parser str+ bad = numErrors y + length s + in case bad of + 0 -> "DFA accepts " ++ str ++ ""+ n -> "DFA rejects " ++ str ++ " with " ++ (show n) ++ " errors."++--testdfa sTART_parseS "caaat"+--testdfa sTART_parseS "cat"+--testdfa sTART_parseS "dog"
@@ -0,0 +1,87 @@+{-# LANGUAGE TypeFamilies+ , ScopedTypeVariables+ , DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances+ , FlexibleContexts+ , RecordWildCards+ , NamedFieldPuns+ , OverloadedStrings #-}++module DFAC where+import Language.Pads.Padsc+import Language.Pads.Testing+import Data.Word++++[pads|+ + -- constrained dfa + -- accepts all caaats with each character followed by a consistent number:+ -- c1a1t1 or c5a5a5a5t5 but not c1a2t2+++ -- START -- _ --> S1+ -- S1 -- c --> S2+ -- S2 -- a --> S3+ -- S3 -- a --> S3+ -- S3 -- t --> ACCEPT+++ data AA = AA {'a','a','a'}++ data START = START {start::S1}++ -- s1 -- c --> s2++ data S1 = S1 {+ 'c',+ c1 :: Char,+ s2 :: S2 c1+ }++ -- s2 -- a --> s3++ data S2 (n::Char) = + S2 { + 'a',+ constrain c2 :: Char where <| n == c2 |>,+ s3 :: S3 c2+ }++ -- s3 -- a --> s3+ -- s3 -- t --> s4++ data S3 (n::Char) = + S3A { 'a', + constrain c3a :: Char where <| n == c3a |>,+ s3a :: S3 c3a + } |+ S3T { 't', + constrain c3t :: Char where <| n == c3t |>,+ ss4 :: S4 c3t}++ data S4 (n::Char) = S4 {s4::ACCEPT}++ data ACCEPT = ACCEPT ()++|]+++testdfa parser str = + let + ((x, (y, z)), s) = parser str+ bad = numErrors y + length s + in case bad of + 0 -> "DFA accepts " ++ str ++ ""+ n -> "DFA rejects " ++ str ++ " with " ++ (show n) ++ " errors."++--testdfa sTART_parseS "c1a1t1"+--testdfa sTART_parseS "c1a1t2"++--testdfa sTART_parseS "c1a1a1a1a1a1a1a1t2"+--testdfa sTART_parseS "c1a1a1a1a1a1a1a1t1"
@@ -0,0 +1,15 @@+{-# LANGUAGE TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables #-} +module DOS where +import Language.Pads.Padsc hiding (take, rest, head) +import Language.Pads.GenPretty +import System.IO.Unsafe (unsafePerformIO) + + +[pads| type Strs = [Line StringLn] terminator EOF |] + +[pads| type StrsWindows = partition Strs using windows |] + +{- should load with no errors -} +(rep,md) = unsafePerformIO $ parseFileWithD windows strs_parseM "data/fig-small.fig" + +(rep1,md1) = unsafePerformIO $ parseFileWith strsWindows_parseM "data/fig-small.fig"
@@ -0,0 +1,992 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,+ MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}++module First where+import Language.Pads.Padsc+import Language.Pads.Testing+import FirstPads+import Language.Haskell.TH++import System.IO.Unsafe (unsafePerformIO)+import Data.Char as Char+import qualified Data.ByteString as B+import Data.Word++--import qualified Text.Regex.ByteString as BRE++ws = REd "[\t ]+|$" " "++---- PADS EXAMPLES++[pads| |]++[pads| type MyChar = Char |]+myChar_result = myChar_parseS "ab"+myChar_expects = ('a', 0,"b")+myChar_test = mkTestCase "myChar" myChar_expects myChar_result++[pads| type IntPair = (Int, '|', Int) |]+intPair_result = intPair_parseS "12|23"+intPair_expects = ((12,23), 0,"")+intPair_test = mkTestCase "intPair" intPair_expects intPair_result++[pads| type Bar = (Int, ',', IntPair, ';', Int) |] -- reference to another named type+bar_result = bar_parseS "256,12|23;456:"+bar_expects = ((256, (12, 23), 456), 0, ":")+bar_test = mkTestCase "bar" bar_expects bar_result++[pads| type Bar2 = (Int, ',', (Int,':',Int), ';', Int) |] -- nested tuple type.+bar2_result = bar2_parseS "56,23:46;29"+bar2_expects = ((56,(23,46),29), 0 ,"")+bar2_test = mkTestCase "bar2" bar2_expects bar2_result++[pads| type BazR = Line (Int, ',', Int) |] -- type that consumes a line boundary.+bazr_result = bazR_parseS "33,33\n"+bazr_expects = ((33,33),0,"")+bazr_test = mkTestCase "bazr" bazr_expects bazr_result++[pads| type MyInt = Int |] -- Integer base type+myInt_result = myInt_parseS "23"+myInt_expects = (23,0,"")+myInt_test = mkTestCase "myInt" myInt_expects myInt_result+++{- String base types -}+testStrLen = 2+computeLen x = x - 1+[pads| type StrTy = StringFW <| testStrLen + (computeLen 4) |> |]+inputStrTy = "catdog"+strTy_results = strTy_parseS inputStrTy+strTy_expects = ("catdo", 0,"g")+strTy_test = mkTestCase "strTy" strTy_expects strTy_results++[pads| type StrTy1 = StringC 'o' |]+strTy1_results = strTy1_parseS inputStrTy+strTy1_expects = ("catd",0,"og")+strTy1_test = mkTestCase "strTy1" strTy1_expects strTy1_results++[pads| type Baz = (StringFW 3,',',Int) |]+input_baz = "cat,123"+baz_results = baz_parseS input_baz+baz_expects = (("cat",123),0,"")+baz_test = mkTestCase "baz" baz_expects baz_results++{- Regular expression types -}+[pads| type StrME = StringME 'a+' |]+input_strME = "aaaab"+strME_results = strME_parseS input_strME++[pads| type StrSE = StringSE <|RE "b|c"|> |]+input_strSE_1 = "aaaab"+input_strSE_2 = "aaaac"+strSE_results_1 = strSE_parseS input_strSE_1+strSE_results_2 = strSE_parseS input_strSE_2++[pads| type StrP1 (x::Int) = StringFW <|x - 1|> |]+input_strP1 = "abcd"+strP1_result = strP1_parseS 3 input_strP1++[pads| type StrHex = StringME '[0-9A-Fa-f]+' |]+input_strHex = "12abcds"+strHex_result = strHex_parseS input_strHex++{- Testing for Phex32FW, which is in Pads.Language.BaseTypes -}+input_hex32FW = "12bc34"+phex32FW_results = phex32FW_parseS 4 input_hex32FW+phex32FW_expects = (4796, 0, "34")+phex32FW_test = mkTestCase "phex32FW" phex32FW_expects phex32FW_results++input2_hex32FW = "00bc34"+strhex32FW_result2 = phex32FW_parseS 4 input2_hex32FW -- ((Phex32FW (188),Errors: 0),"34")++input3_hex32FW = "gbc34"+strhex32FW_result3 = phex32FW_parseS 4 input3_hex32FW -- Prints error message++[pads| type HexPair = (Phex32FW 2, ',', Phex32FW 3) |]+input_hexpair = "aa,bbb"+hexpair_result = hexPair_parseS input_hexpair+++{- Constrained types -}+[pads| type IntRange = constrain x :: Int where <| 0 <= x && x <= 256 |> |]+intRange24_input = "24"+intRange0_input = "0"+intRange256_input = "256"+intRangeLow_input = "-23"+intRangeHigh_input = "512"+intRangeBad_input = "aaa"++result_intRange24 = intRange_parseS intRange24_input+expect_intRange24 = (24,0,"")+test_intRange24 = mkTestCase "IntRange24" expect_intRange24 result_intRange24++result_intRange0 = intRange_parseS intRange0_input+expect_intRange0 = (0,0,"")+test_intRange0 = mkTestCase "IntRange0" expect_intRange0 result_intRange0++result_intRange256 = intRange_parseS intRange256_input+expect_intRange256 = (256,0,"")+test_intRange256 = mkTestCase "IntRange256" expect_intRange256 result_intRange256++result_intRangeLow = intRange_parseS intRangeLow_input+expect_intRangeLow = ((-23),1,"")+test_intRangeLow = mkTestCase "IntRangeLow" expect_intRangeLow result_intRangeLow++result_intRangeHigh = intRange_parseS intRangeHigh_input+expect_intRangeHigh = (512,1,"")+test_intRangeHigh = mkTestCase "IntRangeHigh" expect_intRangeHigh result_intRangeHigh++result_intRangeBad = intRange_parseS intRangeBad_input+expect_intRangeBad = (0,1,"aaa")+test_intRangeBad = mkTestCase "IntRangeBad" expect_intRangeBad result_intRangeBad++{- Note that the special variable "md" is in scope in the body of the predicate. -}+{- md is the meta-data descriptor for the underyling type. -}++[pads| type IntRangeP (low::Int, high::Int) = constrain x :: Int where <| low <= x && x <= high && (numErrors md == 0) |> |]++result_intRangeP24 = intRangeP_parseS (0, 256) intRange24_input+expect_intRangeP24 = (24,0,"")+test_intRangeP24 = mkTestCase "IntRangeP24" expect_intRangeP24 result_intRangeP24++result_intRangeP0 = intRangeP_parseS (0, 256) intRange0_input+expect_intRangeP0 = (0,0,"")+test_intRangeP0 = mkTestCase "IntRangeP0" expect_intRangeP0 result_intRangeP0++result_intRangeP256 = intRangeP_parseS (0, 256) intRange256_input+expect_intRangeP256 = (256,0,"")+test_intRangeP256 = mkTestCase "IntRangeP256" expect_intRangeP256 result_intRangeP256++result_intRangePLow = intRangeP_parseS (0, 256) intRangeLow_input+expect_intRangePLow = ((-23), 1, "")+test_intRangePLow = mkTestCase "IntRangePLow" expect_intRangePLow result_intRangePLow+++result_intRangePHigh = intRangeP_parseS (0, 256) intRangeHigh_input+expect_intRangePHigh = (512, 1,"")+test_intRangePHigh = mkTestCase "IntRangePHigh" expect_intRangePHigh result_intRangePHigh+++result_intRangePBad = intRangeP_parseS (0, 256) intRangeBad_input+expect_intRangePBad = (0, 2,"aaa")+test_intRangePBad = mkTestCase "IntRangePBad" expect_intRangePBad result_intRangePBad+++++[pads| data Record (bound::Int) = Record+ { i1 :: Int,+ ',', i2 :: Int where <| i1 + i2 <= bound |> } |]++input_Record = "24,45"+result_Record = record_parseS 100 input_Record+expect_Record = (Record {i1 = 24, i2 = 45},0,"")+test_Record = mkTestCase "Record" expect_Record result_Record++[pads| data Id = Numeric Int+ | Alpha (StringC ',') |]++input_IdInt = "23"+result_IdInt = id_parseS input_IdInt+expect_IdInt = (Numeric 23,0,"")+test_IdInt = mkTestCase "IdInt" expect_IdInt result_IdInt++input_IdStr = "hello"+result_IdStr = id_parseS input_IdStr+expect_IdStr = (Alpha ("hello"),0,"")+test_IdStr = mkTestCase "IdAlpha" expect_IdStr result_IdStr++[pads| data Id2 (bound::Int) =+ Numeric2 (constrain n::Int where <| n <= bound |>)+ | Alpha2 (StringC ',') |]+input_IdInt2 = "23"+result_IdInt2 = id2_parseS 10 input_IdInt2+expect_IdInt2 = (Alpha2 ("23"),0,"")+test_IdInt2 = mkTestCase "IdInt2" expect_IdInt2 result_IdInt2++input_IdStr2 = "hello"+result_IdStr2 = id2_parseS 10 input_IdStr2+expect_IdStr2 = (Alpha2 ("hello"),0,"")+test_IdStr2 = mkTestCase "IdAlpha2" expect_IdStr2 result_IdStr2++++[pads| data Id3 = Numeric3 (IntRangeP <|(1,10)|>)+ | Numeric3a Int+ | Lit3 ',' |]+input_IdInt3 = "24"+result_IdInt3 = id3_parseS input_IdInt3+expect_IdInt3 = (Numeric3a (24),0,"")+test_IdInt3 = mkTestCase "IdInt3" expect_IdInt2 result_IdInt2++input_IdLit3 = ","+result_IdLit3 = id3_parseS input_IdLit3+expect_IdLit3 = (Lit3,0,"")+test_IdLit3 = mkTestCase "IdLit3" expect_IdLit3 result_IdLit3++++[pads| data Ab_or_a = AB "ab" | A "a" |]+input_AB = "ab"+result_Ab_or_a = ab_or_a_parseS input_AB+expect_Ab_or_a = (AB,0,"")+test_Ab_or_a = mkTestCase "Ab_or_a" expect_Ab_or_a result_Ab_or_a++[pads| data AB_test = AB_test { field_AB :: Ab_or_a , 'b'} |]+input_AB_test1 = "abb"+result_AB_test1 = aB_test_parseS input_AB_test1+expect_AB_test1 = (AB_test {field_AB = AB},0,"")+test_AB_test1 = mkTestCase "AB_test1" expect_AB_test1 result_AB_test1++input_AB_test2 = "ab"+result_AB_test2 = aB_test_parseS input_AB_test2+--expect_AB_test2 = (AB_test {field_AB = A},0,"") -- if backtracking+expect_AB_test2 = (AB_test {field_AB = AB},1,"")+test_AB_test2 = mkTestCase "AB_test2" expect_AB_test2 result_AB_test2++[pads| data Method = GET | PUT | LINK | UNLINK | POST+ data Version = Version+ {"HTTP/"+ , major :: Int, '.'+ , minor :: Int}+|]++checkVersion :: Method -> Version -> Bool+checkVersion method version =+ case method of+ LINK -> major version == 1 && minor version == 0+ UNLINK -> major version == 1 && minor version == 0+ _ -> True++[pads| data Request = Request+ { '"', method :: Method+ , ' ', url :: StringC ' '+ , ' ', version :: Version where <| checkVersion method version |>+ , '"'+ } |]++input_method_get = "GET"+result_method_get = method_parseS input_method_get+expect_method_get = (GET,0,"")+test_method_get = mkTestCase "Method_get" expect_method_get result_method_get++input_method_put = "PUT"+result_method_put = method_parseS input_method_put+expect_method_put = (PUT,0,"")+test_method_put = mkTestCase "Method_put" expect_method_put result_method_put+++input_method_link = "LINK"+result_method_link = method_parseS input_method_link+expect_method_link = (LINK,0,"")+test_method_link = mkTestCase "Method_link" expect_method_link result_method_link+++input_method_post = "POST"+result_method_post = method_parseS input_method_post+expect_method_post = (POST,0,"")+test_method_post = mkTestCase "Method_post" expect_method_post result_method_post+++input_version = "HTTP/1.2"+result_version = version_parseS input_version+expect_version = (Version {major = 1, minor = 2},0,"")+test_version = mkTestCase "Version" expect_version result_version++input_request_G = "\"PUT /www.google.com HTTP/1.0\""+result_request_G = request_parseS input_request_G+expect_request_G = (Request {method = PUT, url = "/www.google.com", version = Version {major = 1, minor = 0}}, 0, "")+test_request_G = mkTestCase "Request_G" expect_request_G result_request_G++input_request_B = "\"LINK /www.google.com HTTP/1.3\""+result_request_B = request_parseS input_request_B+expect_request_B = (Request {method = LINK, url = "/www.google.com", version = Version {major = 1, minor = 3}},1, "")+test_request_B = mkTestCase "Request_B" expect_request_B result_request_B++[pads| type Eor_Test = (Int, EOR, Int) |]+input_eor_test = "23\n56"+result_eor_test = eor_Test_parseS input_eor_test+expect_eor_test = ((23,56),0,"")+test_eor_test = mkTestCase "Eor_Test" expect_eor_test result_eor_test++[pads| type Eof_Test = (Int, EOR, Int, EOF) |]+input_eof_test_G = "23\n56"+result_eof_test_G = eof_Test_parseS input_eof_test_G+expect_eof_test_G = ((23,56),0,"")+test_eof_test_G = mkTestCase "Eof_TestG" expect_eof_test_G result_eof_test_G++input_eof_test_B = "23\n56ab"+result_eof_test_B = eof_Test_parseS input_eof_test_B+expect_eof_test_B = ((23,56), 1,"ab")+test_eof_test_B = mkTestCase "Eof_TestB" expect_eof_test_B result_eof_test_B++{- Restate after Maybe is implemented -}+[pads| type Opt_test = (Int, '|', Maybe Int, '|', Int) |]+input_opt_test_j = "34|35|56"+result_opt_test_j = opt_test_parseS input_opt_test_j+expect_opt_test_j = ((34,Just 35,56),0,"")+test_opt_test_j = mkTestCase "Opt_test_j" expect_opt_test_j result_opt_test_j++input_opt_test_n = "34||56"+result_opt_test_n = opt_test_parseS input_opt_test_n+expect_opt_test_n = ((34,Nothing,56),0,"")+test_opt_test_n = mkTestCase "Opt_test_n" expect_opt_test_n result_opt_test_n+++{- LIST EXAMPLES -}++[pads| type Entries_nosep_noterm = [StringFW 3] |]+input_entries_nosep_noterm = "123456789"+result_entries_nosep_noterm = entries_nosep_noterm_parseS input_entries_nosep_noterm+expect_entries_nosep_noterm = (["123","456","789"],0,"")+test_entries_nosep_noterm = mkTestCase "NoSep_NoTerm" expect_entries_nosep_noterm result_entries_nosep_noterm++input_entries_nosep_noterm' = "1234567890"+result_entries_nosep_noterm' = entries_nosep_noterm_parseS input_entries_nosep_noterm'+expect_entries_nosep_noterm' = (["123","456","789"],0,"0")+test_entries_nosep_noterm' = mkTestCase "NoSep_NoTerm'" expect_entries_nosep_noterm' result_entries_nosep_noterm'++[pads| type Entries_nosep_noterm2 = [Char] |]+input_entries_nosep_noterm2 = ""+result_entries_nosep_noterm2 = entries_nosep_noterm2_parseS input_entries_nosep_noterm2+expect_entries_nosep_noterm2 = ([],0,"")+test_entries_nosep_noterm2 = mkTestCase "NoSep_NoTerm2" expect_entries_nosep_noterm2 result_entries_nosep_noterm2+++[pads| type EvenInt = constrain x :: Digit where <| x `mod` 2 == 0 |>+ type EvenInts = [EvenInt] |]+input_evenInts = "2465"+result_evenInt = evenInt_parseS input_evenInts+expect_evenInt = ( 2,0,"465")+test_evenInt = mkTestCase "EvenInt" expect_evenInt result_evenInt++result_evenInts = evenInts_parseS input_evenInts+expect_evenInts = ([2,4,6],0,"5")+test_evenInts = mkTestCase "EvenInts" expect_evenInts result_evenInts+++[pads| type DigitList = [Digit | ','] |]+input_digitListG = "1,2,3"+input_digitList2G = "1,2,3|fed"+input_digitListB = "1,b,3"+result_digitListG = digitList_parseS input_digitListG+expect_digitListG = ([1,2,3],0,"")+test_digitListG = mkTestCase "DigitListG" expect_digitListG result_digitListG++result_digitList2G = digitList_parseS input_digitList2G+expect_digitList2G = ([1,2,3],0,"|fed")+test_digitList2G = mkTestCase "DigitList2G" expect_digitList2G result_digitList2G++result_digitListB = digitList_parseS input_digitListB+expect_digitListB = ([1],0,",b,3")+test_digitListB = mkTestCase "DigitListB" expect_digitListB result_digitListB++[pads| type DigitListLen (x::Int) = [Digit] length <|x + 1 |> |]+input_digitListLenG = "123456"+input_digitListLenB = "12a456"++result_digitListLenG = digitListLen_parseS 4 input_digitListLenG+expect_digitListLenG = ([1,2,3,4,5],0,"6")+test_digitListLenG = mkTestCase "DigitListLenG" expect_digitListLenG result_digitListLenG++result_digitListLenB = digitListLen_parseS 4 input_digitListLenB+expect_digitListLenB = ([1,2,0,4,5],1 ,"6")+test_digitListLenB = mkTestCase "DigitListLenB" expect_digitListLenB result_digitListLenB+++[pads| type DigitListLenSep (x::Int) = [Digit | "ab" ] length <|x + 1|> |]+input_digitListLenSepG = "1ab2ab3ab4ab5ab6ab7ab"+input_digitListLenSepB = "1ab2ab3abDab5ab6ab7ab"+result_digitListLenSepG = digitListLenSep_parseS 4 input_digitListLenSepG+expect_digitListLenSepG = ([1,2,3,4,5],0,"ab6ab7ab")+test_digitListLenSepG = mkTestCase "DigitListLenSepG" expect_digitListLenSepG result_digitListLenSepG++result_digitListLenSepB = digitListLenSep_parseS 4 input_digitListLenSepB+expect_digitListLenSepB = ([1,2,3,0,5],1,"ab6ab7ab")+test_digitListLenSepB = mkTestCase "DigitListLenSepB" expect_digitListLenSepB result_digitListLenSepB+++[pads| type DigitListTerm = [Digit] terminator EOR|]+input_digitListTermG = "12345\nhello"+result_digitListTermG = digitListTerm_parseS input_digitListTermG+expect_digitListTermG = ([1,2,3,4,5],0,"hello")+test_digitListTermG = mkTestCase "DigitListTermG" expect_digitListTermG result_digitListTermG++input_digitListTermB = "12345,h"+result_digitListTermB = digitListTerm_parseS input_digitListTermB+expect_digitListTermB = ([1,2,3,4,5,0,0],2,"")+test_digitListTermB = mkTestCase "DigitListTermB" expect_digitListTermB result_digitListTermB++[pads| type DigitListTermSep = [Digit | '|' ] terminator ';' |]+input_digitListTermSepG = "1|2|3|4|5|6;hello"+result_digitListTermSepG = digitListTermSep_parseS input_digitListTermSepG+expect_digitListTermSepG = ([1,2,3,4,5,6], 0,"hello")+test_digitListTermSepG = mkTestCase "digitListTermSepG" expect_digitListTermSepG result_digitListTermSepG++input_digitListTermSepB = "1|2|3|4|56;hello"+result_digitListTermSepB = digitListTermSep_parseS input_digitListTermSepB+expect_digitListTermSepB = ([1,2,3,4,5],1,"hello")+test_digitListTermSepB = mkTestCase "digitListTermSepB" expect_digitListTermSepB result_digitListTermSepB++[pads| type TryTest = (Try Char, StringFW 3) |]+input_tryTest = "abc123"+result_tryTest = tryTest_parseS input_tryTest+expect_tryTest = (('a',"abc"),0,"123")+test_tryTest = mkTestCase "tryTest" expect_tryTest result_tryTest++[pads| type TryTestD = (Try Digit, StringFW 3) |]+input_tryTestDG = "123abc"+result_tryTestDG = tryTestD_parseS input_tryTestDG+expect_tryTestDG = ((1,"123"),0,"abc")+test_tryTestDG = mkTestCase "tryTestDG" expect_tryTestDG result_tryTestDG++-- Note that 'try_parseM' does not return an error when it fails to parse a+-- digit (and therefore uses the default value of "0") because a "try" parser+-- should fail silently, similar to how the 'try' combinator works in parsec.+input_tryTestDB = "abc123"+result_tryTestDB = tryTestD_parseS input_tryTestDB+expect_tryTestDB = ((0,"abc"),0,"123")+test_tryTestDB = mkTestCase "tryTestDB" expect_tryTestDB result_tryTestDB++{- ((TryTestD (0,"abc"),+ (Errors: 1 Encountered a when expecting Digit. at: Line: 0, Offset:+ 0,(Errors: 1 Encountered a when expecting Digit. at: Line: 0, Offset:+ 0,Errors: 0))),"123")++ XXX: we are getting a repeat error message because of change to how errors are+ propagated. Need to work on cleaning up error reporting.+-}+++[pads| type ListWithTry = ([Char] terminator (Try Digit), Digit) |]+input_ListWithTry = "cat123"+result_ListWithTry = listWithTry_parseS input_ListWithTry+expect_ListWithTry = ((['c', 'a', 't'],1),0,"23")+test_ListWithTry = mkTestCase "ListWithTry" expect_ListWithTry result_ListWithTry++++[pads| type WithVoid = (Char, ',', Void, '|') |]+input_WithVoid = "a,|rest"+result_WithVoid = withVoid_parseS input_WithVoid+expect_WithVoid = ('a',0,"rest")+test_WithVoid = mkTestCase "WithVoid" expect_WithVoid result_WithVoid++[pads| data VoidOpt = PDigit Digit | Pcolor "red" | Pnothing Void+ type VoidEntry = (VoidOpt, StringFW 3) |]+input_voidEntry1 = "9abcdef"+result_voidEntry1 = voidEntry_parseS input_voidEntry1+expect_voidEntry1 = ((PDigit 9,"abc"),0,"def")+test_voidEntry1 = mkTestCase "VoidEntry1" expect_voidEntry1 result_voidEntry1++input_voidEntry2 = "redabcdef"+result_voidEntry2 = voidEntry_parseS input_voidEntry2+expect_voidEntry2 = ((Pcolor,"abc"),0,"def")+test_voidEntry2 = mkTestCase "VoidEntry2" expect_voidEntry2 result_voidEntry2++input_voidEntry3 = "abcdef"+result_voidEntry3 = voidEntry_parseS input_voidEntry3+expect_voidEntry3 = ((Pnothing,"abc"),0,"def")+test_voidEntry3 = mkTestCase "VoidEntry3" expect_voidEntry3 result_voidEntry3++[pads| data Switch (which :: Int) =+ case <| which |> of+ 0 -> Even Int where <| even `mod` 2 == 0 |>+ | 1 -> Comma ','+ | otherwise -> Missing Void |]+input_switch0 = "2hello"+input_switch1 = ",hello"+input_switchOther = "hello"++result_switch0 = switch_parseS 0 input_switch0+expect_switch0 = (Even (2),0,"hello")+test_switch0 = mkTestCase "switch0" expect_switch0 result_switch0++result_switch1 = switch_parseS 1 input_switch1+expect_switch1 = (Comma,0,"hello")+test_switch1 = mkTestCase "switch1" expect_switch1 result_switch1++result_switchOther = switch_parseS 2 input_switchOther+expect_switchOther = (Missing,0,"hello")+test_switchOther = mkTestCase "switchOther" expect_switchOther result_switchOther++++result_stringln = stringLn_parseS "hello\ngoodbye"+expect_stringln = ("hello",0,"\ngoodbye")+test_stringln = mkTestCase "stringln" expect_stringln result_stringln++[pads| data MyBody (which::Int) =+ case <| which |> of+ 0 -> First Int+ | 1 -> Second (StringC ',')+ | otherwise -> Other Void++ data MyEntry = MyEntry+ { header :: Int, ','+ , body :: MyBody header, ','+ , trailer :: Char}++ type MyData = [Line MyEntry] terminator EOF |]++input_myData = "0,23,a\n1,hello,b\n2,,c\n"+result_myData = myData_parseS input_myData+expect_myData = ([MyEntry {header = 0, body = First (23), trailer = 'a'},+ MyEntry {header = 1, body = Second ("hello"), trailer = 'b'},+ MyEntry {header = 2, body = Other, trailer = 'c'}],0, "")+test_myData = mkTestCase "MyData" expect_myData result_myData++++[pads| data HP = HP { student_num :: Int, ',',+ student_name :: StringFW student_num }+ type HP_data = [Line HP] terminator EOF |]++input_hp_data = "8,Hermione\n3,Ron\n5,Harry\n"+result_hp_data = hP_data_parseS input_hp_data+expect_hp_data = ([HP {student_num = 8, student_name = "Hermione"},+ HP {student_num = 3, student_name = "Ron"},+ HP {student_num = 5, student_name = "Harry"}], 0, "")+test_hp_data = mkTestCase "HP Data" expect_hp_data result_hp_data++++test_file = "examples/data/test_file"+result_hp_data_file_parse :: (HP_data, HP_data_md) = unsafePerformIO $ parseFileWith hP_data_parseM test_file++expect_hp_data_file_parse =+ ( [HP {student_num = 8, student_name = "Hermione"},+ HP {student_num = 3, student_name = "Ron"},+ HP {student_num = 5, student_name = "Harry"}], 0)+test_hp_data_file_parse = mkFileTestCase "HP file" expect_hp_data_file_parse result_hp_data_file_parse++++strToBS = B.pack . (map chrToWord8)++[pads| newtype MyDoc = MyDoc Text |]+myDoc_input_file = "examples/data/test_file"+myDoc_result :: (MyDoc, MyDoc_md) = unsafePerformIO $ parseFile myDoc_input_file+myDoc_expects = (MyDoc (Text (strToBS "8,Hermione\n3,Ron\n5,Harry\n")),0)+myDoc_test = mkFileTestCase "myDoc" myDoc_expects myDoc_result+++acomma = ","+[pads| data LitRec = LitRec { fstField :: Int, acomma, sndField :: Int} |]+litRec_input = "12,34"+litRec_result = litRec_parseS litRec_input+litRec_expects = (LitRec {fstField = 12, sndField = 34},0,"")+litRec_test = mkTestCase "Haskell identifier literal" litRec_expects litRec_result++[pads| type WhiteSpace = (Int, '[ \t]+', Int) |]+whiteSpace_input = "12 34"+whiteSpace_result = whiteSpace_parseS whiteSpace_input+whiteSpace_expects = ((12,34),0,"")+whiteSpace_test = mkTestCase "regular expression literal" whiteSpace_expects whiteSpace_result++++[pads| type WhiteSpace2 = (Int, ws, Int) |]+whiteSpace2_input = "12 34"+whiteSpace2_result = whiteSpace2_parseS whiteSpace2_input+whiteSpace2_expects = ((12,34),0,"")+whiteSpace2_test = mkTestCase "Haskell expression regular expression literal" whiteSpace2_expects whiteSpace2_result++[pads| type RE_ty = (StringME '[tod]', ws, StringME 'a+') |]+rE_ty_input = "t aaaa"+rE_ty_result = rE_ty_parseS rE_ty_input+rE_ty_expects = (("t","aaaa"),0,"")+rE_ty_test = mkTestCase "regular expression abbreviation for StringME" rE_ty_expects rE_ty_result+++[pads| type Disc = (Int, EOR, Int, EOR, (partition (Int, EOR, Int, EOR) using windows), Int, EOR) |]+disc_input = "1\n2\n3\r\n4\r\n5\n"+disc_result = disc_parseS disc_input+disc_expects = ((1,2,(3,4),5),0,"")+disc_test = mkTestCase "multiple record disciplines" disc_expects disc_result++[pads| data Exxy a = Exxy {exxy :: Int, aa :: a}+ type ExxyInt = Exxy Char |]+exxy_input = "32635def"+exxy_result = exxyInt_parseS exxy_input+exxy_expects = (Exxy {exxy = 32635, aa = 'd'},0,"ef")+exxy_test = mkTestCase "label overlap" exxy_expects exxy_result++[pads| type OneLine = [Char] terminator EOR+ type Lines = [OneLine] terminator EOF+ type LinesFW = partition Lines using <| bytes 3 |>+|]++linesFW_input = "123456789"+linesFW_result = linesFW_parseS linesFW_input+linesFW_expects = (["123","456","789"],0,"")+linesFW_test = mkTestCase "fixed-width record discpline" linesFW_expects linesFW_result+++[pads| type Strs = [StringSE ws | ws] terminator EOR |]+strs_input = "0.700264\n"+strs_result = strs_parseS strs_input++[pads| data Vals = Vals { vv :: Int, uu = value <| even vv |> :: Bool, ww::Char} |]+vals_input = "123x"+vals_result = vals_parseS vals_input+vals_expects = (Vals {vv=123,uu=False,ww='x'},0,"")+vals_test = mkTestCase "values" vals_expects vals_result++[pads| data Vals2 = Vals2 { vv2 :: (Int,",",Int),+ uu2 = value <| fst vv2 `mod` snd vv2 == 0 |> :: Bool,+ ww2 :: Char} |]+vals2_input = "12,3x"+vals2_result = vals2_parseS vals2_input+vals2_expects = (Vals2 {vv2=(12,3),uu2=True,ww2='x'},0,"")+vals2_test = mkTestCase "values" vals2_expects vals2_result+++{-+[pads| data Vals3 a = Vals3 { vv3 :: (Int,",",Int),+ uu3 = value <| [] |> :: [a],+ ww3 :: Char} |]+vals3_input = "12,3x"+vals3_result = vals3_parseS vals3_input+vals3_expects = (Vals3 {vv3=(12,3),uu3=[],ww3='x'},0,"")+vals3_test = mkTestCase "values" vals3_expects vals3_result+-}++[pads| type Doubles = [Double | EOR] terminator EOF |]+doubles_input = "12.34\n1\n-12.0\n1.3e4\n1.2e-2"+doubles_result = doubles_parseS doubles_input+doubles_expects = ([12.34,1.0,-12.0,13000.0,1.2e-2],0,"")+doubles_test = mkTestCase "doubles" doubles_expects doubles_result++[pads| type StringSEs = [StringSE <|RE "$"|> | EOR] terminator EOF |]++stringSEs_input = "12.34\n1\n-12.0\n1.3e4\n1.2e-2"+stringSEs_result = stringSEs_parseS stringSEs_input+stringSEs_expects = (["12.34","1","-12.0","1.3e4","1.2e-2"],0,"")+stringSEs_test = mkTestCase "stringSEs" stringSEs_expects stringSEs_result++[pads| type StringFWs = [StringFW 3| EOR] terminator EOF |]+stringFWs_input = "abc\nabcd\nab\nabc"+stringFWs_result = stringFWs_parseS stringFWs_input+stringFWs_expects = (["abc","abc","XXX","abc"],2,"")+stringFWs_test = mkTestCase "stringFWs" stringFWs_expects stringFWs_result+++[pads| type StringESCs = [(StringESC <| ('!', ";,") |>, '[;,]') | EOR] terminator EOF |]+stringESCs_input = "abc\na;\nb,\na!;bc,\na!,cd\nhe!"+stringESCs_result = stringESCs_parseS stringESCs_input+stringESCs_expects = (["abc","a","b","a;bc","a,cd","he!"],4, "")+stringESCs_test = mkTestCase "stringESCs" stringESCs_expects stringESCs_result++[pads| type StringPs = [StringP Char.isDigit | EOR] terminator EOF |]+stringPs_input = "123\na\n123a"+stringPs_result = stringPs_parseS stringPs_input+stringPs_expects = (["123","","123"],2, "")+stringPs_test = mkTestCase "stringPs" stringPs_expects stringPs_result++{- Bit-level functionality tests -}++[pads| type BitBools = (partition [BitBool] using none) |]+bitBools_input = "a" -- binary 01100001+bitBools_result = bitBools_parseS bitBools_input+bitBools_expects = ([False,True,True,False,False,False,False,True], 0, "")+bitBools_test = mkTestCase "bitBools" bitBools_expects bitBools_result++bitBools_input2 = "a\n" -- binary 01100001 00001010+bitBools_result2 = bitBools_parseS bitBools_input2+bitBools_expects2 = ([False,True,True,False,False,False,False,True,+ False,False,False,False,True,False,True,False], 0, "")+bitBools_test2 = mkTestCase "bitBools" bitBools_expects2 bitBools_result2++[pads| type IncompleteBitBools = (partition (BitBool,+ BitBool,+ BitBool) using none) |]+incompleteBitBools_input = "4"+incompleteBitBools_result = incompleteBitBools_parseS incompleteBitBools_input+incompleteBitBools_expects = ((False,False,True), 0, "4")+incompleteBitBools_test = mkTestCase "incompleteBitBools"+ incompleteBitBools_expects+ incompleteBitBools_result++[pads| type ArithPixel = (partition (Bits16 9,+ Bits8 5,+ Bits8 5,+ Bits8 5,+ Bits8 4,+ Bits8 4) using none) |]+arithPixel_input = map word8ToChr [136,114,32,0]+arithPixel_result = arithPixel_parseS arithPixel_input+arithPixel_expects = ((272,28,17,0,0,0), 0, "")+arithPixel_test = mkTestCase "arithPixel" arithPixel_expects arithPixel_result++[pads| type Mixed = (partition (StringC ' ',+ ' ',+ Bits8 4,+ BitBool,+ Bits8 3,+ Char) using none) |]++mixed_input = "Hello " ++ (map word8ToChr [74]) ++ "c"+mixed_result = mixed_parseS mixed_input+mixed_expects = (("Hello",4,True,2,'c'), 0, "")+mixed_test = mkTestCase "mixed" mixed_expects mixed_result++[pads| type OddWidths = (partition (Bits32 19,+ Bits64 39,+ Bits8 1,+ Bits8 5) using none) |]++oddWidths_input = map word8ToChr [104,46,174,3,185,8,6,158]+oddWidths_result = oddWidths_parseS oddWidths_input+oddWidths_expects = ((213365,240768000026,0,30), 0, "")+oddWidths_test = mkTestCase "oddWidths" oddWidths_expects oddWidths_result++[pads| type LargeWidths = (partition (Bits8 7,+ BitField 89,+ BitField 65) using none) |]++largeWidths_input = map word8ToChr [1,0,0,0,0,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,128]+largeWidths_result = largeWidths_parseS largeWidths_input+largeWidths_expects = ((0,309485009821345068724781057,18446744073709551617), 0, map word8ToChr [128])+largeWidths_test = mkTestCase "largeWidths" largeWidths_expects largeWidths_result++[pads| data EnumType (x :: Bits8) = case x of 0 -> ZERO {}+ | 1 -> ONE {}+ | 2 -> TWO {}+ | _ -> OTHER {}++ data Enumerate = Enumerate {x :: Bits8 3,+ Bits8 5,+ y :: EnumType x}++ type Enumerated = (partition Enumerate using none) |]++enumerated_input = map word8ToChr [64]+enumerated_result = enumerated_parseS enumerated_input+enumerated_expects = (Enumerate {x = 2, y = TWO}, 0, "")+enumerated_test = mkTestCase "Enumerated" enumerated_expects enumerated_result++enumerated_input_wc = map word8ToChr [255]+enumerated_result_wc = enumerated_parseS enumerated_input_wc+enumerated_expects_wc = (Enumerate {x = 7, y = OTHER}, 0, "")+enumerated_test_wc = mkTestCase "EnumeratedWC" enumerated_expects_wc enumerated_result_wc++[pads| data EnumTypeBool (x' :: BitBool) = case x' of True -> ON {}+ | False -> OFF {}++ data EnumerateBool = EnumerateBool {Bits8 7,+ x' :: BitBool,+ y' :: EnumTypeBool x'}++ type EnumeratedBool = (partition EnumerateBool using none) |]++enumeratedBool_input = map word8ToChr [1]+enumeratedBool_result = enumeratedBool_parseS enumeratedBool_input+enumeratedBool_expects = (EnumerateBool {x' = True, y' = ON}, 0, "")+enumeratedBool_test = mkTestCase "EnumeratedBool" enumeratedBool_expects enumeratedBool_result++[pads| type NBA_char = (partition (Bits8 3, CharNB, Bits8 5) using none) |]++nBA_char_input = map word8ToChr [70,181] -- 01000110 10110101+nBA_char_result = nBA_char_parseS nBA_char_input+nBA_char_expects = ((2,'5',21), 0, "") -- 010 00110101 10101+nBA_char_test = mkTestCase "NBA_char" nBA_char_expects nBA_char_result++[pads| type NBA_char_aligned = (partition (CharNB, CharNB) using none)|]++nBA_char_aligned_input = map word8ToChr [70,181]+nBA_char_aligned_result = nBA_char_aligned_parseS nBA_char_aligned_input+nBA_char_aligned_expects = ((word8ToChr 70, word8ToChr 181), 0, "")+nBA_char_aligned_test = mkTestCase "NBA_char_aligned" nBA_char_aligned_expects nBA_char_aligned_result++[pads| type NBA_BS = (partition (Bits8 6, BytesNB 2, Bits8 2) using none) |]++nBA_BS_input = map word8ToChr [99,234,3] -- 01100011 11101010 0000011+nBA_BS_result = nBA_BS_parseS nBA_BS_input+nBA_BS_expects = ((24, B.pack [250,128], 3), 0, "")+nBA_BS_test = mkTestCase "NBA_BS" nBA_BS_expects nBA_BS_result++[pads| type NBA_BS_aligned = (partition (BytesNB 4) using none) |]++nBA_BS_aligned_input = map word8ToChr [9,8,7,255]+nBA_BS_aligned_result = nBA_BS_aligned_parseS nBA_BS_aligned_input+nBA_BS_aligned_expects = ((B.pack [9,8,7,255]), 0, "")+nBA_BS_aligned_test = mkTestCase "NBA_BS_aligned" nBA_BS_aligned_expects nBA_BS_aligned_result++[pads| type NBA_BS_empty = (partition (BytesNB 1) using none) |]++nBA_BS_empty_input = ""+nBA_BS_empty_result = nBA_BS_empty_parseS nBA_BS_empty_input+nBA_BS_empty_expects = ((B.singleton 0), 1, "")+nBA_BS_empty_test = mkTestCase "NBA_BS_empty" nBA_BS_empty_expects nBA_BS_empty_result++[pads| type NBA_StringFW = (partition (Bits8 4, StringFWNB 3, Bits8 4) using none) |]++nBA_StringFW_input = map word8ToChr [134,22,38,63] --1000 0110 0001 0110 0010 0110 0011 1111+nBA_StringFW_result = nBA_StringFW_parseS nBA_StringFW_input+nBA_StringFW_expects = ((8,"abc",15),0,"")+nBA_StringFW_test = mkTestCase "NBA_StringFW" nBA_StringFW_expects nBA_StringFW_result++[pads| type NBA_StringFW_aligned = (partition (StringFWNB 15) using none) |]++nBA_StringFW_aligned_input = map word8ToChr (replicate 15 97)+nBA_StringFW_aligned_result = nBA_StringFW_aligned_parseS nBA_StringFW_aligned_input+nBA_StringFW_aligned_expects = (("aaaaaaaaaaaaaaa"),0,"")+nBA_StringFW_aligned_test = mkTestCase "NBA_StringFW_aligned" nBA_StringFW_aligned_expects nBA_StringFW_aligned_result++[pads| type NBA_StringFW_err = (partition (StringFWNB 3) using none) |]++nBA_StringFW_err_input = map word8ToChr [99,99]+nBA_StringFW_err_result = nBA_StringFW_err_parseS nBA_StringFW_err_input+nBA_StringFW_err_expects = (("XXX"),1,"")+nBA_StringFW_err_test = mkTestCase "NBA_StringFW_err" nBA_StringFW_err_expects nBA_StringFW_err_result++[pads| type NBA_StringC = (partition (Bits8 2, StringCNB 'z', CharNB, Bits8 6) using none) |]++nBA_StringC_input = map word8ToChr [158,30,94,149] -- 10 011110 00 011110 01 011110 10 010101+nBA_StringC_result = nBA_StringC_parseS nBA_StringC_input+nBA_StringC_expects = ((2,"xy",'z',21),0,"")+nBA_StringC_test = mkTestCase "NBA_StringC" nBA_StringC_expects nBA_StringC_result++[pads| type NBA_StringC_aligned = (partition (StringCNB 'z') using none) |]++nBA_StringC_aligned_input = "xyz"+nBA_StringC_aligned_result = nBA_StringC_aligned_parseS nBA_StringC_aligned_input+nBA_StringC_aligned_expects = (("xy"),0,"z")+nBA_StringC_aligned_test = mkTestCase "NBA_StringC_aligned" nBA_StringC_aligned_expects nBA_StringC_aligned_result++$(make_pads_declarations $ map snd padsExp)++padsExp_ast =+ [ ("Halloween", PadsDeclType "Halloween" [] Nothing+ ( PList (PApp [PTycon ["StringFW"]] (Just (LitE (IntegerL 4))))+ (Just (PTycon ["EOR"]))+ (Just (LTerm (PTycon ["EOF"])))) Nothing)]+padsExp_input = "karl\njred\nmatt\nsam_"+padsExp_result = halloween_parseS padsExp_input+padsExp_expects = (["karl", "jred", "matt", "sam_"], 0, "")+padsExp_test = TestCase (assertEqual "padsExp" padsExp padsExp_ast) -- mkTestCase "padsExp" padsExp padsExp_ast+padsExp_test2 = mkTestCase "padsExp" padsExp_expects padsExp_result++++-- | Regression tests need to be run from the root directory of the pads-haskell+-- package because the data file paths in these test cases use paths relative to+-- the root.+test = runTestTT (TestList tests)+++tests = [ TestLabel "MyChar" myChar_test+ , TestLabel "IntPair" intPair_test+ , TestLabel "Bar" bar_test+ , TestLabel "Bar2" bar2_test+ , TestLabel "Bazr" bazr_test+ , TestLabel "MyInt" myInt_test+ , TestLabel "StrTy" strTy_test+ , TestLabel "StrTy1" strTy1_test+ , TestLabel "Baz" baz_test+ , TestLabel "Phex32FW" phex32FW_test+ , TestLabel "IntRange" test_intRange24+ , TestLabel "IntRange" test_intRange0+ , TestLabel "IntRange" test_intRange256+ , TestLabel "IntRange" test_intRangeLow+ , TestLabel "IntRange" test_intRangeHigh+ , TestLabel "IntRange" test_intRangeBad+ , TestLabel "IntRangeP" test_intRangeP24+ , TestLabel "IntRangeP" test_intRangeP0+ , TestLabel "IntRangeP" test_intRangeP256+ , TestLabel "IntRangeP" test_intRangePLow+ , TestLabel "IntRangeP" test_intRangePHigh+ , TestLabel "IntRangeP" test_intRangePBad+ , TestLabel "Record" test_Record+ , TestLabel "Id" test_IdInt+ , TestLabel "Id" test_IdStr+ , TestLabel "Id" test_IdInt2+ , TestLabel "Id" test_IdStr2+ , TestLabel "Id3" test_IdInt3+ , TestLabel "Id3" test_IdLit3+ , TestLabel "Ab_or_a" test_Ab_or_a+ , TestLabel "AB_test" test_AB_test1+ , TestLabel "AB_test" test_AB_test2+ , TestLabel "Method" test_method_get+ , TestLabel "Method" test_method_put+ , TestLabel "Method" test_method_link+ , TestLabel "Method" test_method_post+ , TestLabel "Version" test_version+ , TestLabel "Request" test_request_G+ , TestLabel "Request" test_request_B+ , TestLabel "Eor" test_eor_test+ , TestLabel "Eof" test_eof_test_G+ , TestLabel "Eof" test_eof_test_B+ , TestLabel "Opt" test_opt_test_j+ , TestLabel "Opt" test_opt_test_n+ , TestLabel "List" test_entries_nosep_noterm+ , TestLabel "List" test_entries_nosep_noterm'+ , TestLabel "List" test_entries_nosep_noterm2+ , TestLabel "List" test_evenInt+ , TestLabel "List" test_evenInts+ , TestLabel "List" test_digitListG+ , TestLabel "List" test_digitList2G+ , TestLabel "List" test_digitListB+ , TestLabel "List" test_digitListLenG+ , TestLabel "List" test_digitListLenB+ , TestLabel "List" test_digitListLenSepG+ , TestLabel "List" test_digitListLenSepB+ , TestLabel "List" test_digitListTermG+ , TestLabel "List" test_digitListTermB+ , TestLabel "List" test_digitListTermSepG+ , TestLabel "List" test_digitListTermSepB+ , TestLabel "Try" test_tryTest+ , TestLabel "Try" test_tryTestDG+ , TestLabel "Try" test_tryTestDB+ , TestLabel "Try" test_ListWithTry+ , TestLabel "Void" test_WithVoid+ , TestLabel "Void" test_voidEntry1+ , TestLabel "Void" test_voidEntry2+ , TestLabel "Void" test_voidEntry3+ , TestLabel "Switch" test_switch0+ , TestLabel "Switch" test_switch1+ , TestLabel "Switch" test_switchOther+ , TestLabel "Stringln" test_stringln+ , TestLabel "Compound" test_myData+ , TestLabel "Compound" test_hp_data+ , TestLabel "Doc" test_hp_data_file_parse+ , TestLabel "Doc" myDoc_test+ , TestLabel "Literal" litRec_test+ , TestLabel "Literal" whiteSpace_test+ , TestLabel "Literal" whiteSpace2_test+ , TestLabel "Regular Expression" rE_ty_test+ , TestLabel "Discipline" disc_test+ , TestLabel "Overlap" exxy_test+ , TestLabel "Discipline" linesFW_test+ , TestLabel "Values" vals_test+ , TestLabel "Values" vals2_test+ , TestLabel "Double" doubles_test+ , TestLabel "StringSE" stringSEs_test+ , TestLabel "StringFWs" stringFWs_test+ , TestLabel "StringESCs" stringESCs_test+ , TestLabel "StringPs" stringPs_test+ , TestLabel "PadsExp" padsExp_test+ , TestLabel "PadsExp2" padsExp_test2+ , TestLabel "BitBools" bitBools_test+ , TestLabel "BitBools" bitBools_test2+ , TestLabel "ArithPixel" arithPixel_test+ , TestLabel "IncompleteBitBools" incompleteBitBools_test+ , TestLabel "Mixed" mixed_test+ , TestLabel "OddWidths" oddWidths_test+ , TestLabel "LargeWidths" largeWidths_test+ , TestLabel "Enumerated" enumerated_test+ , TestLabel "EnumeratedWC" enumerated_test_wc+ , TestLabel "EnumeratedBool" enumeratedBool_test+ , TestLabel "NBA_char" nBA_char_test+ , TestLabel "NBA_char_aligned" nBA_char_aligned_test+ , TestLabel "NBA_BS" nBA_BS_test+ , TestLabel "NBA_BS_aligned" nBA_BS_aligned_test+ , TestLabel "NBA_BS_empty" nBA_BS_empty_test+ , TestLabel "NBA_StringFW" nBA_StringFW_test+ , TestLabel "NBA_StringFW_aligned" nBA_StringFW_aligned_test+ , TestLabel "NBA_StringFW_err" nBA_StringFW_err_test+ , TestLabel "NBA_StringC" nBA_StringC_test+ , TestLabel "NBA_StringC_aligned" nBA_StringC_aligned_test+ ]
@@ -0,0 +1,8 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,+ MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}+module FirstPads where+import Language.Pads.Padsc++padsExp = [pads| type Halloween = [StringFW 4 | EOR] terminator EOF |]+
@@ -0,0 +1,278 @@+{-# LANGUAGE TypeFamilies + , ScopedTypeVariables + , DeriveDataTypeable + , MultiParamTypeClasses + , TypeSynonymInstances + , TemplateHaskell + , QuasiQuotes + , FlexibleInstances + , FlexibleContexts + , RecordWildCards + , NamedFieldPuns + , OverloadedStrings #-} + +module FullPCAP where + +import Language.Pads.Padsc +import Language.Pads.Testing +import System.IO.Unsafe (unsafePerformIO) + +import qualified Data.ByteString as B +import qualified Language.Pads.Library.LittleEndian as LE +import qualified Language.Pads.Library.BigEndian as BE + + +hx2bs :: [Char] -> B.ByteString +hx2bs zs = + let + -- strip whitespace out + stripws (' ' : xs) = stripws xs + stripws ( x : xs) = x : stripws xs + stripws [] = [] + + -- convert each character to a value + toDigit x = + if elem x ['0'..'9'] + then (chrToWord8 x) - (chrToWord8 '0') + else if elem x ['a'..'f'] + then (chrToWord8 x) - (chrToWord8 'a') + 10 + else error "bad hex" + + -- make a Word8 out of each two characters + pairs (a : b : rest) = + fromIntegral ((16 * toDigit a) + toDigit b) : pairs rest + pairs [] = [] + + in B.pack $ pairs $ stripws zs + + +ports _ 53 = 53 +ports 53 _ = 53 +ports 123 _ = 123 +ports _ 123 = 123 +ports _ _ = 0 + +[pads| + type BfList (x :: Bits32) = Bytes <| (fromIntegral x :: Int) |> + + data MACADDR = MACADDR { + v1 :: Bits8 8, + v2 :: Bits8 8, + v3 :: Bits8 8, + v4 :: Bits8 8, + v5 :: Bits8 8, + v6 :: Bits8 8 + } + + data NTP = NTP { + ntp_li :: Bits8 2, + ntp_vn :: Bits8 3, + ntp_mode :: Bits8 3, + ntp_stratum :: Bits8 8, + ntp_poll :: Bits8 8, + ntp_precision :: Bits8 8, + ntp_root_delay :: NTPS, + ntp_root_dispersion :: NTPS, + ntp_reference_id :: Bits32 32, + ntp_reference_timestamp :: NTPTS, + ntp_origin_timestamp :: NTPTS, + ntp_receive_timestamp :: NTPTS, + ntp_transmit_timestamp :: NTPTS + -- , + -- ntp_extension_field_1 :: NTPEF, + -- ntp_extension_field_2 :: NTPEF, + -- ntp_key_identifier :: Bits32 32, + -- ntp_dgst :: Bits64 64 + } + + data NTPS = NTPS { + ntps_seconds :: Bits16 16, + ntps_fraction :: Bits16 16 + } + + data NTPTS = NTPTS { + ntpts_seconds :: Bits32 32, + ntpts_fraction :: Bits32 32 + } + + data NTPDF = NTPDF { + ntpdf_era_number :: Bits32 32, + ntpdf_era_offset :: Bits32 32, + ntpdf_fraction :: Bits64 64 + } + + type MACADDR' = partition MACADDR using none + type NTPTS' = partition NTPTS using none + type NTPS' = partition NTPS using none + type NTPDF' = partition NTPDF using none + type NTP' = partition NTP using none + + + type PCAP = partition (PCAP_Header, [Packet]) using none + + data PCAP_Header = PCAP_Header { + magic_number :: LE.Int32, + version_major :: LE.Int16, + version_minor :: LE.Int16, + this_zone :: LE.Int32, + sig_figs :: LE.Int32, + snap_len :: LE.Int32, + network :: LE.Int32 + } + + data Packet = Packet { + ts_sec :: LE.Int32, + ts_usec :: LE.Int32, + incl_len :: LE.Int32, + orig_len :: LE.Int32, + body :: ETHERNET <| fromIntegral incl_len |> + --body :: BfList <| fromIntegral incl_len |> + } + + + data ETHERNET (n :: Bits32) = ETHERNET { + destaddr_eth :: MACADDR, + sourceaddr_eth :: MACADDR, + ethertype_val :: Bits16 16, + ether_body :: IP4 <| n - 14 |> + } + + data IP4 (n :: Bits32) = IP4 { + ip4_version :: Bits8 4, + ip4_header_len :: Bits8 4, + ip4_type_of_service :: Bits8 8, + ip4_total_length :: Bits16 16, + ip4_identification :: Bits16 16, + ip4_a :: BitBool, + ip4_b :: BitBool, + ip4_c :: BitBool, + ip4_fragment_offset :: Bits16 13, + ip4_time_to_live :: Bits8 8, + ip4_protocol :: Bits8 8, + ip4_header_checksum :: Bits16 16, + ip4_source_address :: Bits32 32, + ip4_destination_address :: Bits32 32, + ip4_options :: BfList <| (fromIntegral (ip4_header_len * 4) :: Bits32) - 20 |>, + ip4_body :: PROT <| (ip4_protocol,n - (4 * (fromIntegral ip4_header_len :: Bits32))) |> + } + + data PROT (protocol :: Bits8, prot_len :: Bits32) = + case protocol + of 6 -> PROTCP {tt:: TCP <| prot_len |> } + | 17 -> PROUDP {uu:: UDP <| prot_len |>} + | _ -> OTHERWISE {oo:: BfList <| prot_len |>} + + data TCP (n :: Bits32) = TCP { + tcp_source_port :: Bits16 16, + tcp_destination_port :: Bits16 16, + tcp_sequence_number :: Bits32 32, + tcp_acknowledgment_number :: Bits32 32, + tcp_offset :: Bits8 4, + tcp_reserved :: Bits8 6, + tcp_u :: BitBool, + tcp_a :: BitBool, + tcp_p :: BitBool, + tcp_r :: BitBool, + tcp_s :: BitBool, + tcp_f :: BitBool, + tcp_window :: Bits16 16, + tcp_checksum :: Bits16 16, + tcp_urgent_pointer :: Bits16 16, + tcp_options :: BfList <| 32 * ((fromIntegral tcp_offset) - 5) |>, + tcp_data :: BfList <| (n - 20) - (32 * ((fromIntegral tcp_offset )-5)) |> + } + + data UDP (n:: Bits32) = UDP { + udp_source_port :: Bits16 16, + udp_dest_port :: Bits16 16, + udp_length :: Bits16 16, + udp_checksum :: Bits16 16, + udp_body :: UDPPORT <| ( (ports (fromIntegral udp_source_port :: Bits32) (fromIntegral udp_dest_port :: Bits32)), n - 8) |> + } + + data UDPPORT (udp_port :: Bits32, n :: Bits32) = + case udp_port + of 53 -> DNSP {dnsp:: BfList <| n |>} + | 123 -> NTPP {ntpp:: BfList <| n |>} + | _ -> OTHERWISEP {otherwisep :: BfList <| n |>} +|] + +((h, ps), md) = unsafePerformIO $ parseFileWith pCAP_parseM "data/NTP_sync.pcap" + +((h2, ps2), md2) = unsafePerformIO $ parseFileWith pCAP_parseM "data/another.pcap" + +test = runTestTT (TestList tests) + +tests = [ TestLabel "macaddr" macaddr_test + , TestLabel "ntpts" ntpts_test + , TestLabel "ntps" ntps_test + , TestLabel "ntpdf" ntpdf_test + , TestLabel "ntp" ntp_test + ] + +macaddr_input = "10 0f 23 ad b3 4c" +macaddr_result = parseByteStringInput mACADDR'_parseM (hx2bs macaddr_input) +macaddr_expects = + (MACADDR { + v1 = 16, + v2 = 15, + v3 = 35, + v4 = 173, + v5 = 179, + v6 = 76 + }, 0, "") +macaddr_test = mkTestCase "macaddr" macaddr_expects macaddr_result + +ntpts_input = "c50204ecec42ee92" +ntpts_result = parseByteStringInput nTPTS'_parseM (hx2bs ntpts_input) +ntpts_expects = + (NTPTS { + ntpts_seconds = 3305243884, + ntpts_fraction = 3963809426 + }, 0, "") +ntpts_test = mkTestCase "ntpts" ntpts_expects ntpts_result + +ntps_input = "4a30 94fe" +ntps_result = parseByteStringInput nTPS'_parseM (hx2bs ntps_input) +ntps_expects = + (NTPS { + ntps_seconds = 18992, + ntps_fraction = 38142 + }, 0, "") +ntps_test = mkTestCase "ntps" ntps_expects ntps_result + +ntpdf_input = "54a9002b 3e12fff4 0ab0173d492b029c" +ntpdf_result = parseByteStringInput nTPDF'_parseM (hx2bs ntpdf_input) +ntpdf_expects = + (NTPDF { + ntpdf_era_number = 1420361771, + ntpdf_era_offset = 1041432564, + ntpdf_fraction = 770141088268354204 + }, 0, "") +ntpdf_test = mkTestCase "ntpdf" ntpdf_expects ntpdf_result + +ntp_input = "1a020aef00000f7a000776dd11fe0031c4fae6e5108637bdc50204ecec42ee92c50204ebd937d1fec50204ebd93dea46" +ntp_result = parseByteStringInput nTP'_parseM (hx2bs ntp_input) +ntp_expects = + (NTP { + ntp_li = 0, + ntp_vn = 3, + ntp_mode = 2, + ntp_stratum = 2, + ntp_poll = 10, + ntp_precision = 239, + ntp_root_delay = + NTPS {ntps_seconds = 0, ntps_fraction = 3962}, + ntp_root_dispersion = + NTPS {ntps_seconds = 7, ntps_fraction = 30429}, + ntp_reference_id = 301858865, + ntp_reference_timestamp = + NTPTS {ntpts_seconds = 3304777445, ntpts_fraction = 277231549}, + ntp_origin_timestamp = + NTPTS {ntpts_seconds = 3305243884, ntpts_fraction = 3963809426}, + ntp_receive_timestamp = + NTPTS {ntpts_seconds = 3305243883, ntpts_fraction = 3644314110}, + ntp_transmit_timestamp = + NTPTS {ntpts_seconds = 3305243883, ntpts_fraction = 3644713542} + }, 0, "") +ntp_test = mkTestCase "ntp" ntp_expects ntp_result
@@ -0,0 +1,101 @@+{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, NamedFieldPuns, ScopedTypeVariables #-}+module HPROF where+import Language.Pads.Padsc+import Language.Pads.Library.LittleEndian as LE+import qualified Language.Pads.Library.BigEndian as BE+import qualified Language.Pads.Library.Native as Native+import Language.Pads.Testing+import System.IO.Unsafe (unsafePerformIO)++-- the format specified in:+-- https://java.net/downloads/heap-snapshot/hprof-binary-format.html++[pads| + type U4 = BE.Word32+ type U2 = BE.Word16++ -- total header length: 31 = 19 + 4 + 4 + 4+ data Header = Header+ { version :: [Char] length <| 19 |> + , idsiz :: U4+ , time_hw :: U4+ , time_lw :: U4 }+ -- TODO: can we convert this to the date and hard code it?+ -- 00 00 01 2b 87 5b 95 3e+ -- 299 2270926142+ -- 1286466147646 = October 7th, 2010+ -- http://www.epochconverter.com/+ data Hprof = Hprof+ { hdr :: Header+ -- , entry :: Entry+ , entries :: Entries -- Originally EntriesB+ , theRest :: [Word8] }+ + -- total entry length: 9 + len = 1 + 4 + 4 + len where len is determined by the tag field+ data Entry = Entry+ { tag :: Word8+ , time :: U4+ , len :: U4+ -- fromIntegral :: (Integral a, Num b) => a -> b+ , body :: Body <| (fromIntegral(tag) :: Int, fromIntegral(len) :: Int) |> + -- , body2 :: Body <| (fromIntegral(tag) :: Int, fromIntegral(len) :: Int) |>+}++ -- ???: Why does fromIntegral work here?++ -- !!: Want each Entry to take as many bytes as it needs, and the parser starts reading the next byte as a new Entry+ type Entries = [Entry] terminator EOF -- ?? [Entry | EOR] + -- type EntriesB = partition Entries using <| bytes 6 |>+ -- ?? Does the list type always have to have corresponding terminator and partition declaration?+ + type ID = U4 -- !! should take idsiz from the Header++ data Body (tag :: Int, len :: Int) =+ case <| tag |> of+ 1 -> One -- ?? One and Two never declared...+ { oneid :: ID+ , str :: [Char] length <| len - 4 |> } -- !! should be len - idsiz. len - (idsiz hdr)+ | 2 -> Two + { clsserial :: U4+ , objid :: ID + , stkserial :: U4+ , clsnamestrid :: ID }+ | 3 -> Three + { clsserial :: Word32 }+ | 4 -> Four + { stkframeid :: ID+ , method_nameid :: ID+ , method_sigid :: ID+ , srcfile_nameid :: ID+ , clsserial :: Word32+ , stkInfo :: [Word8] } -- !! should take an argument+ | 14 -> Fourteen+ { bitmask :: U4 -- bizarre case: using 32 bits when you need 1+ , stkdepth :: U2+ --, next :: Word8 + -- , rest :: [Word8] + }+ | otherwise -> Other [Word8]++-- Limitations:+-- One cannot access Header->idsiz from inside of an Entry type?+-- ++|]++hprof_input_file = "Examples/data/specjbb.hprof"+-- hprof_result :: (Header, Header_md) = unsafePerformIO $ parseFileWith header_parseM hprof_input_file+hprof_result :: (Hprof, Hprof_md) = unsafePerformIO $ parseFileWith hprof_parseM hprof_input_file++-- more readable result+result = fst hprof_result++-- returns first n entries+taken n = Prelude.take n $ entries result++-- gets the nth element. index starts at 1.+getnth n = Prelude.head $ Prelude.drop (n-1) $ entries result++hdrlen = 31+-- returns the number of bytes consumed to read n entries+lenupto n = hdrlen + (foldr (+) 0 $ map ((+9) . len) $ Prelude.take n $ entries result)
@@ -0,0 +1,119 @@+{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, + MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}++module HmmPlusOrig where+import Language.Pads.Padsc+import Language.Pads.GenPretty+import Control.Monad+import System.IO.Unsafe (unsafePerformIO)++ws = REd "[\t ]+|$" "foo"++amino = "ACDEFGHIKLMNPQRSTVWY"+nucleotide = "ACTG"++[pads|+ data SmurfFile = SmurfFile { header::SmurfHeader, hmm::HMM <| getAlphabet header |> }+ + type SmurfHeader = [Line HeaderLine] terminator Try (LitRE 'HMM ')+-- type SmurfHeader = [Line HeaderLine] terminator EOF+ + data HeaderLine = HeaderLine { tag::Tag, ws, payload::Payload tag }+ + data Tag = FileVersion "HMMER3/a" -- this string literal will change with major file version changes+ | NAME | ACC | DESC | LENG | ALPH | RF | CS | MAP | DATE | MEAN | RMSD+ | COM | NSEQ | EFFN | CKSUM | GA | TC | NC | STATS | BETA | Other (StringSE ws)+ + data Payload (t::Tag) = case t of+ FileVersion -> Version VersionString+ | NAME -> Name StringLn+ | ACC -> Accession StringLn+ | DESC -> Description StringLn+ | LENG -> ModelLength Int+ | ALPH -> Alphabet StringLn+ | RF -> ReferenceAnnotation StringLn+ | CS -> ConsensusStructure StringLn+ | MAP -> MapAnnotation StringLn+ | DATE -> Date StringLn+ | COM -> CommandLog StringLn+ | NSEQ -> SequenceNumber Int+ | EFFN -> EffectiveSeq Double+ | CKSUM -> Checksum Int+ | GA -> PfamGathering (Double, ws, Double)+ | TC -> PfamTrusted (Double, ws, Double)+ | NC -> PfamNoise (Double, ws, Double)+ | STATS -> Stats {"LOCAL", ws, scoredist::ScoreDistribution, ws, values::[Double | ws] terminator (Try EOR) }+ | BETA -> Beta StrandPair+ | Other tag -> BadTag StringLn+ | otherwise -> OtherTag StringLn+ + type VersionString = StringLn+ + data ScoreDistribution = VLAMBDA | VMU | FTAU | MSV | VITERBI | FORWARD+ + -- firstRes secondRes Length maxGap parallelism exposure+ data StrandPair = StrandPair {+ firstStart :: Int, ' ',+ secondStart :: Int, ' ',+ pairLength :: Int, ' ',+ maxGap :: Int, ' ',+ parallel :: Int, ' ',+ exposure :: StringLn+ }+ + + data HMM (alphabet::String) = HMM {+ "HMM", ws, hmmAlphabet::[Letter alphabet | ws] length <| length alphabet |>, ws, EOR,+ ws, transitionHeader::TransitionDescription, EOR,+ composition::Maybe (ws, "COMPO", ws, EmissionProbabilities alphabet, ws, EOR),+ insertZeroEmissions::InsertEmissions alphabet,+ stateZeroTransitions::StateTransitions <| length transitionHeader |>,+ nodes::[HmmNode <| (alphabet, length transitionHeader ) |>] terminator "//" }+-- rest::[StringLn | EOR] terminator EOF }+ + type Letter (alphabet::String) = constrain c::Char where <| c `elem` alphabet |>+ + type EmissionProbabilities (alphabet::String) = [ Double | ws ] length <| length alphabet |> + + type TransitionProbabilities (numStates::Int) = [ LogProbability | ws ] length numStates+ + type TransitionDescription = [ StringSE ws | ws] terminator (Try EOR)+ + type InsertEmissions (alphabet::String) = (ws, EmissionProbabilities alphabet, ws, EOR)+ + type StateTransitions (numStates::Int) = (ws, TransitionProbabilities numStates, ws, EOR)+ + data HmmNode (alphabet::String, numStates::Int) = HmmNode {+ ws, nodeNum::Int, ws, matchEmissions::EmissionProbabilities alphabet, ws, annotations::EmissionAnnotationSet, EOR,+ insertionEmissions::InsertEmissions alphabet,+ transitions::StateTransitions numStates+ }+ + type EmissionAnnotationSet = (EmissionAnnotation, ws, EmissionAnnotation, ws, EmissionAnnotation)+ + data EmissionAnnotation = MAPA Int+ | Unused '-'+ | RForCS Char+ + + + data LogProbability = NonZero Double+ | LogZero '*'++|]++getAlphabet :: SmurfHeader -> String+getAlphabet header = amino -- replace this with actual code to search the HeaderLine list+++result = do+ { (SmurfFile header hmm, md) <- parseFile "Examples/data/test.hmm+"+ ; return (header, hmm, md)+ }+++result2= do+ { (header, md) <- parseFileWith smurfHeader_parseM "Examples/data/hmmSmall"+ ; return (header, md)+ }
@@ -0,0 +1,64 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, + MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}+module IntPair where++import Language.Pads.Padsc+++import Data.Data+import Data.Int +import qualified Data.ByteString as B +import Data.Word++--test = parseStringInput trip_parseM "354;;23|53|43(652%%35)4;hefd"+++[pads| ++type IntPair a = (Line Int,":",a)++--type Line a = (a, "||")+++data MyVoid = Myvoid Void++++data Trip = Trip (Int, ";;", Lst CharPair, value 34::Int, Foo Int , EOR) ++newtype Lst a = Lst ([a | '|'] length 3)+ deriving Read++data CharPair = Char2 {first::Char,second::Char}++data Foo b = Bazz Int | Zipp "(" b '[01]+' !Int ')'+ deriving (Read, Eq)++data Switcher (x::Int) = case x of+ 0 -> Zero "$"+ | 1 -> One (Lst Int)+ deriving (Read, Eq)++type Triple = (Int, (obtain Char from Int using <|(bi,ib)|>, Int)) ++type MyOtherVoid = ()+++data May a = Jus a+ | Noth ()+++data Exxy a = Exxy {exxy :: Int, Char, aa :: a}+|]+++++bi::a->(Int,Int_md)->(Char,Char_md)+bi x = undefined+ib y = undefined++++
@@ -0,0 +1,77 @@+{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances #-}+module Main where+import System.IO.Unsafe (unsafePerformIO)+import Data.Monoid+import Test.Framework+import Test.Framework.Providers.HUnit+import Test.Framework.Providers.QuickCheck2+import qualified Test.HUnit as H+import Test.HUnit ((@?=))+import Test.QuickCheck (Property, quickCheck, (==>))+import qualified Test.QuickCheck.Monadic as TQM+import Control.Monad.State.Lazy (liftIO)++import Language.Pads.Padsc+import Proc+import qualified First as First+import qualified AI as AI+import qualified Binary as Binary++procMaps fn =+ let (MapsFile maps, maps_md) = unsafePerformIO $ parseFileWith mapsFile_parseM fn+ in last maps+ @?=+ Region { start_addr = "ffffffffff600000"+ , end_addr = "ffffffffff601000"+ , perms = Permissions+ { permRead = READ+ , permWrite = NOWRITE+ , permExec = EXEC+ , permShare = PRIVATE+ }+ , offset = 0+ , device = ("00", "00")+ , inode = 0+ , path = VSyscall+ }++testFirst =+ unsafePerformIO First.test+ @?=+ H.Counts (length First.tests) (length First.tests) 0 0++testAI = True ==> TQM.monadicIO $ do+ r <- liftIO $ AI.result 1+ TQM.assert $ r ==+ [ AI.Entry+ { AI.host = AI.Addr 207 136 97 49+ , AI.identdID = AI.Missing+ , AI.httpID = AI.Missing+ , AI.time = read "1997-10-16 01:46:51 UTC"+ , AI.request = AI.Request+ { AI.method = AI.GET+ , AI.url = "/turkey/amnty1.gif"+ , AI.version = AI.Version {AI.major = 1, AI.minor = 0}+ }+ , AI.response = 200+ , AI.contentLen = AI.ContentLength 3013+ }+ ]++testBinary =+ unsafePerformIO Binary.test+ @?=+ H.Counts (length Binary.tests) (length Binary.tests) 0 0++main :: IO ()+main = defaultMainWithOpts+ [ testCase "First" testFirst+ , testProperty "AI" testAI+ , testCase "proc maps file 0" (procMaps "examples/data/maps0")+ ] mempty+
@@ -0,0 +1,27 @@+{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, + MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}++module One where+import Language.Pads.Padsc++{-+[pads| type IntPair = (Int, '|', Int) |]+intPair_result = intPair_parseS "12|23"+intPair_expects = ((12,23), 0,"")+-}++[pads|+ data Version = Version {"HTTP/", major :: Int, '.', minor :: Int} -- add constriants on major and minor mode+ |]++{-+[pads| data Record (bound::Int) = Record + { i1 :: Int, + ',', i2 :: Int where <| i1 + i2 <= bound |> } |]++-}++[pads| data Record (bound::Int) = Record + { i1 :: Int, + ',', i2 :: Int where <| i1 + i2 <= bound |> } |]
@@ -0,0 +1,202 @@+{-# LANGUAGE DeriveDataTypeable+ , DeriveGeneric+ , DeriveLift+ , FlexibleContexts+ , FlexibleInstances+ , MultiParamTypeClasses+ , QuasiQuotes+ , ScopedTypeVariables+ , TemplateHaskell+ , TypeFamilies+ , TypeSynonymInstances+ , UndecidableInstances #-}++module PCAPBodyFill where++import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.State+import qualified Data.ByteString.Char8 as B+import Data.Time.Clock.POSIX (getPOSIXTime)+import Data.Word+import System.IO.Unsafe++import Language.Pads.Padsc++-- Generation logic: generate as many packets as are needed to send the given+-- data (in this case a webpage), then go back through and fill their random+-- bodies with equally-sized pieces of the meaningful data - avoids changing+-- length fields in the packet (inclLen, ipv4TotLen) except for the last packet++-- Potential easy change: generate packets not all the same size, fix lengths+-- after the fact - should be a small change in fillBody and the original+-- generator for inclLen++-- See PCAPBodyGen.hs for an alternate approach+++fI :: (Num b, Integral a) => a -> b+fI = fromIntegral++mtu :: Num a => a+mtu = 1460++[pads|+ type Bytes' (x :: Int) = Bytes <| max 0 x |>++ type PCAP = partition (PCAPHeader, Packets) using none++ data PCAPHeader = PCAPHeader {+ pchMagicNum :: Bits32 32 generator <| return 0xa1b2c3d4 |>,+ pchVersionMaj :: Bits16 16 generator <| return 2 |>,+ pchVersionMin :: Bits16 16 generator <| return 4 |> ,+ pchThisZone :: Bits32 32 generator <| return 0 |>,+ pchSigFigs :: Bits32 32 generator <| return 0 |>,+ pchSnapLen :: Bits32 32,+ pchNetwork :: Bits32 32 generator <| return 1 |>+ }++ data Packets = Packets { ps :: [Packet] generator ps_genM }++ data Packet = Packet {+ tsSec :: Bits32 32 generator <| liftIO $ floor <$> getPOSIXTime |>,+ tsUsec :: Bits32 32 generator <| randNumBound 999999999 |>,+ inclLen :: Bits32 32 generator <| return $ mtu + 54 |>,+ origLen :: Bits32 32 generator <| return inclLen |>,+ body :: Ethernet inclLen+ }++ data Ethernet (inclLen :: Bits32) = Ethernet {+ ethDst :: MacAddr,+ ethSrc :: MacAddr,+ ethType :: Bits16 16 generator <| return 2048 |>,+ ethPayload :: EthPayload <| (ethType, inclLen) |>+ }++ data MacAddr = MacAddr {+ constrain m1 :: Bits8 8 where <| m1 `mod` 2 == 0 |>,+ m2 :: Bits8 8,+ m3 :: Bits8 8,+ m4 :: Bits8 8,+ m5 :: Bits8 8,+ m6 :: Bits8 8+ }++ data EthPayload (ethType :: Bits16, inclLen :: Bits32) = case ethType of+ 2048 -> IPV4 {+ ipv4Version :: Bits8 4 generator <| return 4 |>,+ ipv4IHL :: Bits8 4 generator <| return 5 |>,+ ipv4DSCP :: Bits8 6,+ ipv4ECN :: Bits8 2,+ ipv4TotLen :: Bits16 16 generator <| return (max 0 $ (fI inclLen) - 14) |>,+ ipv4ID :: Bits16 16,+ ipv4Flags :: IPV4Flags,+ ipv4FragOff :: Bits16 13 generator <| return 0 |>,+ ipv4TTL :: Bits8 8,+ ipv4Protocol :: Bits8 8 generator <| return 6 |>,+ ipv4Cksum :: Bits16 16,+ ipv4Src :: Bits32 32,+ ipv4Dst :: Bits32 32,+ ipv4Opts :: Bytes <| 4 * (max 0 $ (fI ipv4IHL) - 5) |>,+ ipv4Payload :: IPV4Payload <| (ipv4Protocol, ipv4IHL, ipv4TotLen) |>+ }++ data IPV4Flags = IPV4Flags {+ ipv4Res :: BitBool generator <| return False |>,+ ipv4DF :: BitBool,+ ipv4MF :: BitBool generator <| return False |>+ }++ data IPV4Payload (prot :: Bits8, ipv4IHL :: Bits8, totLen :: Bits16) = case prot of+ 6 -> TCP {+ tcpSrc :: Bits16 16 generator <| return 80 |>,+ tcpDst :: Bits16 16,+ tcpSeq :: Bits32 32,+ tcpAck :: Bits32 32,+ tcpOffset :: Bits8 4 generator <| return 5 |>,+ tcpReserved :: Bits8 3 generator <| return 0 |>,+ tcpFlags :: TCPFlags,+ tcpWindow :: Bits16 16,+ tcpCksum :: Bits16 16,+ tcpUrgPtr :: Bits16 16,+ tcpOptions :: Bytes <| 4 * (max 0 $ (fI tcpOffset) - 5) |>,+ tcpPayload :: Bytes' <| (fI totLen) - (fI $ (tcpOffset * 4) + (ipv4IHL * 4)) |>+ }++ data TCPFlags = TCPFlags {+ tcpNS :: BitBool,+ tcpCWR :: BitBool,+ tcpECE :: BitBool,+ tcpURG :: BitBool,+ tcpACK :: BitBool,+ tcpPSH :: BitBool,+ tcpRST :: BitBool generator <| return False |>,+ tcpSYN :: BitBool,+ tcpFIN :: BitBool+ }+|]+++-- | One-stop shop for packet list generation - working at the level of a list+-- of packets, we simply call down to packet_genM then map over its results to+-- perform our filling+ps_genM :: PadsGen st [Packet]+ps_genM = do+ bs <- liftIO $ B.pack <$> minify <$> readFile "data/galois.html"+ let padding = B.replicate (mtu - (B.length bs `mod` mtu)) '\NUL'+ let bs' = B.append bs padding+ ps <- replicateM (B.length bs' `div` mtu) packet_genM+ return $ fillBodies bs ps++ where+ -- | Uses State monad to keep track of what/how many bytes/packets are left+ fillBodies :: B.ByteString -> [Packet] -> [Packet]+ fillBodies bytes packets = do+ fst $ runState (mapM fillBody packets) (bytes, packets)++ -- | Construct a modified packet, changing only the body (and the lengths of+ -- the last packet). Would be cleaner with lenses probably+ fillBody :: Packet -> State (B.ByteString, [Packet]) Packet+ fillBody p = do+ (bs, ps) <- get+ let nextBytes = B.take mtu bs+ let restBytes = B.drop mtu bs+ let nextPacket = head ps+ let restPackets = tail ps+ put (restBytes, restPackets)++ let tcpPayload' = nextBytes+ let ipv4Payload' = (ipv4Payload (ethPayload (body p))) { tcpPayload = tcpPayload' }+ let ethPayload' = (ethPayload (body p)) { ipv4Payload = ipv4Payload' }+ let body' = (body p) { ethPayload = ethPayload' }+ let p' = p { body = body' {+ ethPayload = ethPayload' {+ ipv4Payload = ipv4Payload' {+ tcpPayload = tcpPayload' } } } }++ if B.length nextBytes < mtu+ then let+ inclLen' = fromIntegral $ B.length nextBytes + 54+ ipv4TotLen' = fromIntegral $ B.length nextBytes + 40+ in return p' { inclLen = inclLen', origLen = inclLen', body = body' {+ ethPayload = ethPayload' {+ ipv4TotLen = ipv4TotLen' } } }+ else return p'++-- | Small procedure to remove unnecessary HTML formatting spaces+minify :: String -> String+minify = unlines .+ map (dropWhile (== ' ')) .+ filter (any (/= ' ')) .+ lines++-- | Write a generated PCAP, as well as the HTML from all its packets - can be+-- opened to (visually, roughly) ensure no data has been lost/the HTML hasn't+-- been corrupted+writePCAP :: IO PCAP+writePCAP = do+ pcap <- runPadsGen pCAP_genM+ B.writeFile "data/test.pcap" $ (fromChunks . fromCL . pCAP_serialize) pcap+ let bs = map (tcpPayload . ipv4Payload . ethPayload . body) ((ps . snd) pcap)+ B.writeFile "data/maybeGalois.html" (B.concat bs)+ return pcap
@@ -0,0 +1,192 @@+{-# LANGUAGE DeriveDataTypeable+ , DeriveGeneric+ , DeriveLift+ , FlexibleContexts+ , FlexibleInstances+ , MultiParamTypeClasses+ , QuasiQuotes+ , ScopedTypeVariables+ , TemplateHaskell+ , TypeFamilies+ , TypeSynonymInstances+ , UndecidableInstances #-}++module PCAPBodyGen where++import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.State+import qualified Data.ByteString.Char8 as B+import Data.IORef+import Data.Time.Clock.POSIX (getPOSIXTime)+import Data.Word+import System.IO.Unsafe++import Language.Pads.Padsc++-- Generation logic: don't generate random bodies, make the custom tcpPayload+-- generator read from an IORef acting as a global variable, taking as many+-- bytes as possible - inclLen generator reads from the same ref to ensure+-- correct lengths at the packet header stage, which will propagate down through+-- the packet++-- See PCAPBodyFill.hs for an alternate approach+++fI :: (Num b, Integral a) => a -> b+fI = fromIntegral++mtu :: Num a => a+mtu = 1460++[pads|+ type Bytes' (x :: Int) = Bytes <| max 0 x |>++ type PCAP = partition (PCAPHeader, Packets) using none++ data PCAPHeader = PCAPHeader {+ pchMagicNum :: Bits32 32 generator <| return 0xa1b2c3d4 |>,+ pchVersionMaj :: Bits16 16 generator <| return 2 |>,+ pchVersionMin :: Bits16 16 generator <| return 4 |> ,+ pchThisZone :: Bits32 32 generator <| return 0 |>,+ pchSigFigs :: Bits32 32 generator <| return 0 |>,+ pchSnapLen :: Bits32 32,+ pchNetwork :: Bits32 32 generator <| return 1 |>+ }++ data Packets = Packets { ps :: [Packet] generator ps_genM }++ data Packet = Packet {+ tsSec :: Bits32 32 generator <| liftIO $ floor <$> getPOSIXTime |>,+ tsUsec :: Bits32 32 generator <| randNumBound 999999999 |>,+ inclLen :: Bits32 32 generator inclLen_genM,+ origLen :: Bits32 32 generator <| return inclLen |>,+ body :: Ethernet inclLen+ }++ data Ethernet (inclLen :: Bits32) = Ethernet {+ ethDst :: MacAddr,+ ethSrc :: MacAddr,+ ethType :: Bits16 16 generator <| return 2048 |>,+ ethPayload :: EthPayload <| (ethType, inclLen) |>+ }++ data MacAddr = MacAddr {+ constrain m1 :: Bits8 8 where <| m1 `mod` 2 == 0 |>,+ m2 :: Bits8 8,+ m3 :: Bits8 8,+ m4 :: Bits8 8,+ m5 :: Bits8 8,+ m6 :: Bits8 8+ }++ data EthPayload (ethType :: Bits16, inclLen :: Bits32) = case ethType of+ 2048 -> IPV4 {+ ipv4Version :: Bits8 4 generator <| return 4 |>,+ ipv4IHL :: Bits8 4 generator <| return 5 |>,+ ipv4DSCP :: Bits8 6,+ ipv4ECN :: Bits8 2,+ ipv4TotLen :: Bits16 16 generator <| return (max 0 $ (fI inclLen) - 14) |>,+ ipv4ID :: Bits16 16,+ ipv4Flags :: IPV4Flags,+ ipv4FragOff :: Bits16 13 generator <| return 0 |>,+ ipv4TTL :: Bits8 8,+ ipv4Protocol :: Bits8 8 generator <| return 6 |>,+ ipv4Cksum :: Bits16 16,+ ipv4Src :: Bits32 32,+ ipv4Dst :: Bits32 32,+ ipv4Opts :: Bytes <| 4 * (max 0 $ (fI ipv4IHL) - 5) |>,+ ipv4Payload :: IPV4Payload <| (ipv4Protocol, ipv4IHL, ipv4TotLen) |>+ }++ data IPV4Flags = IPV4Flags {+ ipv4Res :: BitBool generator <| return False |>,+ ipv4DF :: BitBool,+ ipv4MF :: BitBool generator <| return False |>+ }++ data IPV4Payload (prot :: Bits8, ipv4IHL :: Bits8, totLen :: Bits16) = case prot of+ 6 -> TCP {+ tcpSrc :: Bits16 16 generator <| return 80 |>,+ tcpDst :: Bits16 16,+ tcpSeq :: Bits32 32,+ tcpAck :: Bits32 32,+ tcpOffset :: Bits8 4 generator <| return 5 |>,+ tcpReserved :: Bits8 3 generator <| return 0 |>,+ tcpFlags :: TCPFlags,+ tcpWindow :: Bits16 16,+ tcpCksum :: Bits16 16,+ tcpUrgPtr :: Bits16 16,+ tcpOptions :: Bytes <| 4 * (max 0 $ (fI tcpOffset) - 5) |>,+ tcpPayload :: Bytes' <| (fI totLen) - (fI $ (tcpOffset * 4) + (ipv4IHL * 4)) |> generator tcpPayload_genM+ }++ data TCPFlags = TCPFlags {+ tcpNS :: BitBool,+ tcpCWR :: BitBool,+ tcpECE :: BitBool,+ tcpURG :: BitBool,+ tcpACK :: BitBool,+ tcpPSH :: BitBool,+ tcpRST :: BitBool generator <| return False |>,+ tcpSYN :: BitBool,+ tcpFIN :: BitBool+ }+|]++-- | Global-variable-acting reference to data to fill bodies with. Tuple is+-- actual bytes of data, number of bytes of data, and desired length of packet+-- bodies+{-# NOINLINE ref #-}+ref :: IORef (B.ByteString, Int, Int)+ref = unsafePerformIO $ do+ bs <- B.pack <$> minify <$> readFile "data/galois.html"+ newIORef (bs, B.length bs, 1460)++ps_genM :: PadsGen st [Packet]+ps_genM = do+ (_, availLen, desiredLen) <- liftIO $ readIORef ref+ case availLen `mod` desiredLen of+ 0 -> replicateM (availLen `div` desiredLen) packet_genM+ _ -> replicateM (1 + (availLen `div` desiredLen)) packet_genM++-- | As long as possible, limited by availLen from ref - doesn't update ref,+-- that's tcpPayload_genM's job+inclLen_genM :: PadsGen st Bits32+inclLen_genM = do+ (_, availLen, desiredLen) <- liftIO $ readIORef ref+ return $ 54 + (fromIntegral $ min availLen desiredLen)++-- | Grab however much data possible from the ref - put back in the ref the+-- updated state after the grab. After the last bytes are taken, reset the ref+-- to allow for repeated generation+tcpPayload_genM :: PadsGen st Bytes'+tcpPayload_genM = do+ (bs, availLen, desiredLen) <- liftIO $ readIORef ref+ if availLen >= desiredLen+ then do+ liftIO $ writeIORef ref (B.drop desiredLen bs, availLen - desiredLen, desiredLen)+ return $ B.take desiredLen bs+ else do+ -- resetting the ref+ bs' <- liftIO $ B.pack <$> minify <$> readFile "data/galois.html"+ liftIO $ writeIORef ref (bs', B.length bs', 1460)+ return $ B.take availLen bs++-- | Small procedure to remove unnecessary HTML formatting spaces+minify :: String -> String+minify = unlines .+ map (dropWhile (== ' ')) .+ filter (any (/= ' ')) .+ lines++-- | Write a generated PCAP, as well as the HTML from all its packets - can be+-- opened to (visually, roughly) ensure no data has been lost/the HTML hasn't+-- been corrupted+writePCAP :: IO PCAP+writePCAP = do+ pcap <- runPadsGen pCAP_genM+ B.writeFile "data/test.pcap" $ (fromChunks . fromCL . pCAP_serialize) pcap+ let bs = map (tcpPayload . ipv4Payload . ethPayload . body) ((ps . snd) pcap)+ B.writeFile "data/maybeGalois.html" (B.concat bs)+ return pcap
@@ -0,0 +1,49 @@+{-# LANGUAGE UndecidableInstances, FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, NamedFieldPuns, ScopedTypeVariables #-}+module Pnm where+import qualified Data.Char as Char+import Language.Pads.Padsc +import Control.Monad+import Language.Pads.Library.Native++_ws = one_or_more Char.isSpace+ where one_or_more = undefined++ws, wsnl, whitechar :: RE++ws = REd "[ \t\n\r]+" " " -- whitespace+wsnl = let REd wplus _ = ws in REd wplus "\n" -- whitespace output as \n+whitechar = REd "[ \t\n\r]" "\n" -- one white character+++[pads|++-- data PGMx a = PGM "P5" ws Header whitechar (Pixmap a)++ data Header = Header -- fields should be separated by whitespace+ { width :: Int+ , ws , height :: Int+ , wsnl , constrain denominator :: Int where <| 0 <= denominator && denominator < 65536 |>+ }++ data Pixmap a (h::Header) = Rows ([Row a h | wsnl] length <| height h |>)+ data Row a (h::Header) = Pixels ([a | ws] length <| width h |>)++ newtype Greypix (h::Header) =+ G (constrain g :: Int where <| 0 <= g && g <= denominator h |>)++-- data PGM = PGMx Int16 Greypix++|]++--pgm file = do+-- (rep, md) <- parseFile file+-- return rep+++++++++
@@ -0,0 +1,51 @@+{-# LANGUAGE TypeFamilies, ScopedTypeVariables, DeriveDataTypeable+ , MultiParamTypeClasses+ , TypeSynonymInstances+ , TemplateHaskell+ , QuasiQuotes+ , FlexibleInstances #-}+-- :set -ddump-splices+module Proc where+import Language.Pads.Padsc++ws = RE "[ \t]+"++[pads|++ newtype MapsFile = MapsFile ([Line Region] terminator EOF)+ + data Region = Region+ { start_addr :: Hex+ , '-', end_addr :: Hex+ , ' ', perms :: Permissions+ , ' ', offset :: Int+ , ' ', device :: (Hex, ':', Hex)+ , ' ', inode :: Int+ , ws , path :: RegionName+ }++ type Hex = StringME '[0-9A-Fa-f]+'++ data RegionName =+ Heap "[heap]"+ | Stack "[stack]"+ | VDSO "[vdso]"+ | VVAR "[vvar]"+ | VSyscall "[vsyscall]"+ | Path ([Char] terminator EOR)+ | Anonymous ""++ data Permissions = Permissions+ { permRead :: RP+ , permWrite :: WP+ , permExec :: XP+ , permShare :: SP+ }++ data RP = READ 'r' | NOREAD '-'+ data WP = WRITE 'w' | NOWRITE '-'+ data XP = EXEC 'x' | NOEXEC '-'+ data SP = SHARE 's' | PRIVATE 'p'++|]+
@@ -0,0 +1,336 @@+{-# LANGUAGE NamedFieldPuns,RecordWildCards #-}++module Regression where++import Text.PrettyPrint.Mainland.Class+import Text.PrettyPrint.Mainland as PP+import Language.Pads.Syntax+import qualified Language.Pads.Parser as P+import Language.Pads.RegExp++import Text.Parsec.Error +import Language.Pads.Pretty++++testParsePadsDecls :: String -> Either ParseError [PadsDecl]+testParsePadsDecls input = P.parsePadsDecls "test" 0 0 input ++ppDeclList decls = stack (map ppr decls)++results+ = [result1, result2, result3, result4, result5, result6, result7,+ result8, result9, result10, result11, result12, result13, result14,+ result15, result16, result17, result18, result19, result20, result21,+ result22, result23, result24, result25, result26, result27, result28,+ result29, result30, result31, result32, result33, result34, result35,+ result36, result37, result38, result39, result40, result41, result42,+ result43, result44, result45, result46, result47, result48, result49,+ result50, result51, result52, result53+ ]+result = and results+failures = [n | (r,n) <- zip results [1..], not r]++---------------------+++t1 = "type MyChar = Char"+pt1 = testParsePadsDecls t1+ppt1 = case pt1 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result1 = t1 == ppt1++t2 = "type IntPair = (Int, '|', Int)"+pt2 = testParsePadsDecls t2+ppt2 = case pt2 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result2 = t2 == ppt2+++t3 = "type Bar = (Int, ',', IntPair, ';', Int)"+pt3 = testParsePadsDecls t3+ppt3 = case pt3 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result3 = t3 == ppt3++t4 = "type Bar2 = (Int, ',', (Int, ':', Int), ';', Int)"+pt4 = testParsePadsDecls t4+ppt4 = case pt4 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result4 = t4 == ppt4++t5 = "type BazR = Line (Int, ',', Int)"+pt5 = testParsePadsDecls t5+ppt5 = case pt5 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result5 = t5 == ppt5+++t6 = "type StrTy = StringFW <|testStrLen + computeLen 4|>"+pt6 = testParsePadsDecls t6+ppt6 = case pt6 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result6 = t6 == ppt6++t7 = "type StrTy1 = StringC 'o'"+pt7 = testParsePadsDecls t7+ppt7 = case pt7 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result7 = t7 == ppt7++t8 = "type Baz = (StringFW 3, ',', Int)"+pt8 = testParsePadsDecls t8+ppt8 = case pt8 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result8 = t8 == ppt8++t9 = "type StrME = StringME \"a+\""+pt9 = testParsePadsDecls t9+ppt9 = case pt9 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result9 = t9 == ppt9++t10 = "type StrP1 (x :: Int) = StringFW <|x - 1|>"+pt10 = testParsePadsDecls t10+ppt10 = case pt10 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result10 = t10 == ppt10++t11 = "newtype IntRange = IntRange (constrain x :: Int where <|(0 <= x) && (x <= 256)|>)"+pt11 = testParsePadsDecls t11+ppt11 = case pt11 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result11 = t11 == ppt11++t12 = "type IntRangeP (low :: Int, high :: Int) = constrain x :: Int where <|(low <= x) && ((x <= high) && (numErrors x_md == 0))|>"+pt12 = testParsePadsDecls t12+ppt12 = case pt12 of Left e -> show e ; Right r -> pretty 80 (ppDeclList r)+result12 = t12 == ppt12++t13 = "data Record (bound :: Int) = Rec {i1 :: Int, ',', i2 :: Int} where <|(i1 + i2) <= bound|>"+pt13 = testParsePadsDecls t13+ppt13 = case pt13 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result13 = t13 == ppt13++t14 = "data Record2 (bound :: Int) = Rec2 {i1 :: Int, ',', i2 :: Int where <|(i1 + i2) <= bound|>}"+pt14 = testParsePadsDecls t14+ppt14 = case pt14 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result14 = t14 == ppt14++t15 = "data Id = Numeric Int | Alpha (StringC ',')"+pt15 = testParsePadsDecls t15+ppt15 = case pt15 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result15 = t15 == ppt15++t16 = "data Id3 = Numeric3 (IntRangeP <|(1, 10)|>) | Numeric3a Int | Lit3 ','"+pt16 = testParsePadsDecls t16+ppt16 = case pt16 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result16 = t16 == ppt16++t17 = "data Ab_or_a = AB \"ab\" | A \"a\""+pt17 = testParsePadsDecls t17+ppt17 = case pt17 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result17 = t17 == ppt17++t18 = "data AB_test = AB_test {field_AB :: Ab_or_a, 'b'}"+pt18 = testParsePadsDecls t18+ppt18 = case pt18 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result18 = t18 == ppt18++t19 = "data Method = GET | PUT | LINK | UNLINK | POST"+pt19 = testParsePadsDecls t19+ppt19 = case pt19 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result19 = t19 == ppt19++t20 = "data Version = Version {\"HTTP/\", major :: Int, '.', minor :: Int}"+pt20 = testParsePadsDecls t20+ppt20 = case pt20 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result20 = t20 == ppt20++t21 = "data Request = Request {'\"', method :: Method, ' ', url :: StringC ' ', ' ', version :: Version where <|checkVersion method version|>, '\"'}"+pt21 = testParsePadsDecls t21+ppt21 = case pt21 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result21 = t21 == ppt21++t22 = "type Eor_Test = (Int, Eor, Int)"+pt22 = testParsePadsDecls t22+ppt22 = case pt22 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result22 = t22 == ppt22++t23 = "type Eof_Test = (Int, Eor, Int, Eof)"+pt23 = testParsePadsDecls t23+ppt23 = case pt23 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result23 = t23 == ppt23++t24 = "type Opt_test = (Int, '|', Maybe Int, '|', Int)" +pt24 = testParsePadsDecls t24+ppt24 = case pt24 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result24 = t24 == ppt24++t25 = "type Entries_nosep_noterm = [StringFW 3]"+pt25 = testParsePadsDecls t25+ppt25 = case pt25 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result25 = t25 == ppt25++t26 = "type Entries_nosep_noterm2 = [Char]"+pt26 = testParsePadsDecls t26+ppt26 = case pt26 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result26 = t26 == ppt26++t27 = "type EvenInt = constrain x :: Digit where <|(x `mod` 2) == 0|>"+pt27 = testParsePadsDecls t27+ppt27 = case pt27 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result27 = t27 == ppt27++t28 = "type DigitList = [Digit | ',']"+pt28 = testParsePadsDecls t28+ppt28 = case pt28 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result28 = t28 == ppt28++t29 = "type DigitListLen (x :: Int) = [Digit] length <|x + 1|>"+pt29 = testParsePadsDecls t29+ppt29 = case pt29 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result29 = t29 == ppt29++t30 = "type DigitListLenSep (x :: Int) = [Digit | \"ab\"] length <|x + 1|>"+pt30 = testParsePadsDecls t30+ppt30 = case pt30 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result30 = t30 == ppt30++t31 = "type DigitListTerm = [Digit] terminator Eor"+pt31 = testParsePadsDecls t31+ppt31 = case pt31 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result31 = t31 == ppt31++t32 = "type DigitListTermSep = [Digit | '|'] terminator ';'"+pt32 = testParsePadsDecls t32+ppt32 = case pt32 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result32 = t32 == ppt32++t33 = "type TryTest = (Try Char, StringFW 3)"+pt33 = testParsePadsDecls t33+ppt33 = case pt33 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result33 = t33 == ppt33++t34 = "type ListWithTry = ([Char] terminator Try Digit, Digit)"+pt34 = testParsePadsDecls t34+ppt34 = case pt34 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result34 = t34 == ppt34++t35 = "type WithVoid = (Char, ',', Void, '|')"+pt35 = testParsePadsDecls t35+ppt35 = case pt35 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result35 = t35 == ppt35++t36 = "data VoidOpt = PDigit Digit | Pcolor \"red\" | Pnothing Void"+pt36 = testParsePadsDecls t36+ppt36 = case pt36 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result36 = t36 == ppt36++t37 = "type VoidEntry = (VoidOpt, StringFW 3)"+pt37 = testParsePadsDecls t37+ppt37 = case pt37 of Left e -> show e ; Right r -> pretty 100 (ppDeclList r)+result37 = t37 == ppt37++t38 = "data Switch (which :: Int) = case which of 0 -> Even Int where <|(even `mod` 2) == 0|> | 1 -> Comma ',' | otherwise -> Missing Void"+pt38 = testParsePadsDecls t38+ppt38 = case pt38 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result38 = t38 == ppt38++t39 = "data MyBody (which :: Int) = case which of 0 -> First Int | 1 -> Second (StringC ',') | otherwise -> Other Void"+pt39 = testParsePadsDecls t39+ppt39 = case pt39 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result39 = t39 == ppt39++t40 = "data MyEntry = MyEntry {header :: Int, ',', body :: MyBody header, ',', trailer :: Char}"+pt40 = testParsePadsDecls t40+ppt40 = case pt40 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result40 = t40 == ppt40++t41 = "type MyData = [Line MyEntry] terminator Eof"+pt41 = testParsePadsDecls t41+ppt41 = case pt41 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result41 = t41 == ppt41++t42 = "data HP = HP {student_num :: Int, ',', student_name :: StringFW <|pintToInt student_num|>}"+pt42 = testParsePadsDecls t42+ppt42 = case pt42 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result42 = t42 == ppt42++t43 = "type HP_data = [Line HP]"+pt43 = testParsePadsDecls t43+ppt43 = case pt43 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result43 = t43 == ppt43++acomma = ','+t44 = "data LitRec = LitRec {fstField :: Int, acomma, sndField :: Int}"+-- "data LitRec = LitRec {fstField :: Int, acomma :: Int, sndField :: Int}"+pt44 = testParsePadsDecls t44+-- Urgh. Parses as multiple Int fields.+ppt44 = case pt44 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result44 = t44 == ppt44++t45 = "type WhiteSpace = (Int, '[ \\t]+', Int)"+pt45 = testParsePadsDecls t45+ppt45 = case pt45 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result45 = t45 == ppt45++ws = RE "[ \t]+"+t46 = "type WhiteSpace2 = (Int, ws, Int)"+pt46 = testParsePadsDecls t46+ppt46 = case pt46 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result46 = t46 == ppt46++t47 = "type RE_ty = (Pre \"[tod]\", ws, Pre \"a+\")"+pt47 = testParsePadsDecls t47+ppt47 = case pt47 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result47 = t47 == ppt47++t48 = "type Pstringln = Line (constrain x :: PstringSE \"$\" where True)"+pt48 = testParsePadsDecls t48+ppt48 = case pt48 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result48 = t48 == ppt48++t49 = "type Phex32FW (size :: Int) = transform StringFW size => Int using <|(hexStr2Int, int2HexStr size)|>"+pt49 = testParsePadsDecls t49+ppt49 = case pt49 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result49 = t49 == ppt49++t50 = "type Int = transform StringME \"[0..9]+\" => Int using <|(s2i, i2s)|>"+pt50 = testParsePadsDecls t50+ppt50 = case pt50 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result50 = t50 == ppt50++t51 = "type Char = transform StringFW 1 => Char using <|(head, \\x -> [x])|>"+pt51 = testParsePadsDecls t51+ppt51 = case pt51 of Left e -> show e ; Right r -> pretty 151 (ppDeclList r)+result51 = t51 == ppt51++t52 = "type Fun a b = transform b => (a -> b) using <|(const, \\f -> f def)|>"+t52' = "type Fun a b = transform b => (->) a b using <|(const, \\f -> f def)|>"+pt52 = testParsePadsDecls t52+ppt52 = case pt52 of Left e -> show e ; Right r -> pretty 152 (ppDeclList r)+result52 = t52' == ppt52++t53 = "type StrTy = PstringFW <|testStrLen + computeLen 4|>"+pt53 = testParsePadsDecls t53+ppt53 = case pt53 of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+result53 = t53 == ppt53++t54 = "data HP = HP {student_num :: Pint, ',', student_name :: PstringFW <|pintToInt student_num|>}\ntype HP_data = [Line HP]"+pt54 = testParsePadsDecls t54+ppt54 = case pt54 of Left e -> show e ; Right r -> pretty 250 (ppDeclList r)+result54 = t54 == ppt54++(t55,pt55,ppt55,result55) = (t,pt,ppt,result)+ where+ t = "newtype Void = Void ()"+ pt = testParsePadsDecls t+ ppt = case pt of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+ result = t == ppt+ +(t56,pt56,ppt56,result56) = (t,pt,ppt,result)+ where+ t = "type Foo = Baz '[a-z+]'"+ pt = testParsePadsDecls t+ ppt = case pt of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+ result = t == ppt++(t57,pt57,ppt57,result57) = (t,pt,ppt,result)+ where+ t = "type BazR = Line (Pint, ',', Pint)"+ pt = testParsePadsDecls t+ ppt = case pt of Left e -> show e ; Right r -> pretty 150 (ppDeclList r)+ result = t == ppt+++
@@ -0,0 +1,33 @@+{-# LANGUAGE TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables #-}+module Small where+import Language.Pads.Padsc++[pads| type StringFWs = [StringFW 3| EOR] terminator EOF |]+stringFWs_input = "abc\nabcd\nab\nabc"+stringFWs_result = stringFWs_parseS stringFWs_input+stringFWs_expects = (["abc","abc","XXX","abc"],2,"")++{-+The first error has the wrong line number; the second error has the correct one.+((["abc","abc","XXX","abc"],(Errors: 2 Extra bytes: d before seperator. at: Line: 3, Offset: 0,[Errors: 0 ,Errors: 1 Extra bytes: d before seperator. at: Line: 3, Offset: 0,Errors: 1 Found 2 bytes when looking for 3bytes. at: Line: 3, Offset: 2,Errors: 0 ])),"")++Also, test arrays with nullable element types. Does this cause an infinite loop?++-}+typeRE = REd "TYPE|type" "TYPE"++[pads| data EmailType = EmailInternet "INTERNET"+ | EmailX400 "X400"+ | EmailPreferred (StringME 'PREF|pref')+ | EmailWork "WORK"+ type CommaL a = [a|','] terminator Try (Lit ";") + type TypeL a = [(typeRE, '=', CommaL a) | ';'] terminator ':'+ type EList = TypeL EmailType ++|]++commaL_input = "type=INTERNET;type=WORK;type=pref:"+commaL_result = eList_parseS commaL_input+++
@@ -0,0 +1,341 @@+{-# LANGUAGE TypeFamilies, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables, TypeSynonymInstances #-}++module VCard+ ( -- $doc+ VCard(..)+ , CommonName+ , IndividualNames(..)+ , VCardProperty(..)+ , AddrType(..)+ , TelType(..)+ , EmailType(..)+ , AgentData(..)+ , VCardData(..)+ , Class(..)+ ) where++import Data.List (intercalate)+import Data.Time (UTCTime, TimeZone, FormatTime, formatTime)++import Language.Pads.Padsc++-- Lines are delimited with carriage return/line-feed (control-M, newline) \r\n+-- Nested Vcards are separated by \n rather than \r\n++[pads|+-- KSF: Added to describe sequence of VCards+newtype VCards = VCards (partition [Line VCard] terminator EOF using windows)++-- KSF: moved IndividualNames and Common Name into VCardPropety because these attributes are not+-- guaranteed to be in a particular order.+data VCard = VCard ("BEGIN:", vcardRE, EOR, [Line Entry] terminator "END:", vcardRE)++data Entry = Entry { prefix :: Maybe ("item", Int, '.'),+ tag :: Tag,+ sep :: StringME colonsemiRE,+ property :: VCardProperty tag }++data Tag = VERSION | FN | NICKNAME | BDAY | ADR | LABEL+ | TEL | EMAIL | MAILER | TZ |GEO | TITLE | ROLE | LOGO | AGENT+ | ORG | CATEGORIES | NOTE | PRODID | REV | SORTSTRING "SORT-STRING"+ | SOUND | UID | URL | CLASS | KEY+ | EXTENSION ("X-", VCardString)+ | ITEM "item"+ | PHOTO+ | N+++data VCardProperty (tag :: Tag) = case tag of+ -- | Version number of VCard file format+ VERSION -> Version (Int, '.', Int)++ -- | A breakdown of the vCard entity's name, as described by IndividualNames+ | N -> Names IndividualNames++ -- | Formated name of the represented person+ --+ -- > CommonName "Mr. Michael A. F. Schade"+ | FN -> FName VCardString++ -- | A list of nicknames belonging to the VCard entity. E.g.,+ --+ -- > Nickname ["Mike", "Mikey"]+ | NICKNAME -> Nickname NameSs++ -- | A photo of the VCard entity. E.g.,+ --+ -- > Photo Nothing (URI "http://accentuate.us/smedia/images/michael.jpg")+ | PHOTO -> Photo VCardData++ -- | Specifies the birth date of the VCard entity. E.g.,+ --+ | BDAY -> Birthday { bdayType :: Maybe ("value=date:", ())+ , bdate :: DateFSE <| ("%Y-%m-%d", RE "$") |>+ }+ -- | A physical address associated with the vCard entity. E.g.,+ --+ -- > Address [AddrParcel, AddrPostal] "PO Box 935" "" "" "Fenton" "MO"+ -- > "63026" "USA"+ | ADR -> Address { addrType :: TypeL AddrType+ , poBox :: VCardString, ';'+ , extAddress :: VCardString, ';'+ , streetAddress :: VCardString, ';'+ , locality :: VCardString, ';' -- ^ City+ , region :: VCardString, ';' -- ^ State or Province+ , postalCode :: VCardString, ';'+ , countryName :: VCardString+ }+ -- | Formatted text about the delivery address. This is typically similar+ -- to the information in Address. E.g.,+ --+ -- > Label [AddrParcel, AddrPostal]+ -- > ["Michael Schade", "PO Box 935", "Fenton, MO 63026"]+ | LABEL -> Label { labelType :: TypeL AddrType+ , label :: VCardString+ }+ -- | A telephone number for the VCard entity, as well as a list of+ -- properties describing the telephone number. E.g.,+ --+ -- > Telephone [TelCell, TelPreferred] "+1-555-555-5555"+ | TEL -> Telephone { telType :: TypeL TelType+ , number :: VCardString+ }+ -- | An email address for the VCard entity, including a list of properties+ -- describing it. E.g.,+ --+ -- > Email [EmailInternet, EmailPreferred] "hackage@mschade.me"+ | EMAIL -> Email { emailType :: TypeL EmailType+ , emailAddr :: VCardString+ }+ -- | Specifies the mailing agent the vCard entity uses. E.g.,+ --+ -- > Mailer "MichaelMail 4.2" -- Not a real mailing agent, unfortunately :(+ | MAILER -> Mailer VCardString+ -- | Represents the time zone of the vCard entity. E.g.,+ --+ -- > TZ (hoursToTimeZone (-6))+ | TZ -> Tz TZone++ -- | Relates to the global positioning of the vCard entity. The value is+ -- (latitude, longitude) and must be specified as decimal degrees,+ -- preferably to six decimal places.+ --+ -- > Geo (37.386013, -122.082932)+ | GEO -> Geo (Double, ';', Double)+ -- | The VCard entity's job title or other position. E.g.,+ --+ -- > Title "Co-Founder"+ | TITLE -> Title VCardString+ -- | Specifies the role associated with the title. E.g.,+ --+ -- > Role "Anything" -- For the co-founder, or+ -- > Role "Programmer" -- For someone the title "Research and Development"+ | ROLE -> Role VCardString+ -- | An image of the vCard entity's logo. This would typically relate to+ -- their organization. E.g.,+ --+ -- > Logo Nothing (URI "http://spearheaddev.com/smedia/images/logo-trans.png")+ | LOGO -> Logo VCardData+ -- | Indicates the vCard of an assistant or area administrator who is+ -- typically separately addressable. E.g.,+ --+ -- > Agent (AgentURI "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com")+ --+ -- or+ --+ -- > Agent (AgentVCard (VCard [ CommonName "James Q. Helpful"+ -- > , Email [EmailInternet] "j@spearheaddev.com"+ -- > ]))+ | AGENT -> Agent AgentData+ -- | The organization to which an entity belongs followed by organizational+ -- unit names. E.g.,+ --+ -- > Organization ["Spearhead Development, L.L.C.", "Executive"]+ | ORG -> Organization ([VCardString | ';'] terminator LitRE ';$|$')+ -- | General categories to describe the vCard entity. E.g.,+ --+ -- > Categories ["Internet", "Web Services", "Programmers"]+ | CATEGORIES -> Categories ([VCardString | ','] terminator Try EOR)+ -- | A general note about the vCard entity. E.g.,+ --+ -- > Note "Email is the absolute best contact method."+ | NOTE -> Note VCardString+ -- | Specifies the identifier of the product that created this vCard. E.g.,+ --+ -- > ProductId "-//ONLINE DIRECTORY//NONSGML Version 1//EN"+ --+ -- Please note well that, by RFC 2426 guidelines, \"implementations SHOULD+ -- use a method such as that specified for Formal Public Identifiers in ISO+ -- 9070 to assure that the text value is unique,\" but this module does not+ -- support that.+ | PRODID -> ProductId VCardString+ -- | Distinguishes the current revision from other renditions. E.g.,+ --+ -- > Revision $ UTCTime (fromGregorian 2011 04 16) (secondsToDiffTime 0)+ | REV -> Revision { revDate :: DateFSE <|("%Y-%m-%d", RE "T")|>+ , revTime :: Maybe ('T', DateFSE <|("%H-%M-%SZ", RE "$")|>)+ }+ -- | Provides a locale- or national-language-specific formatting of the+ -- formatted name based on the vCard entity's family or given name. E.g.,+ --+ -- > SortString "Schade"+ | SORTSTRING -> SortString VCardString+ -- | Specifies information in a digital sound format to annotate some+ -- aspect of the vCard. This is typically for the proper pronunciation of the+ -- vCard entity's name. E.g.,+ --+ -- > Sound "BASIC"+ -- > (URI "CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@host1.com")+ | SOUND -> Sound { sndType :: Maybe (TypeS, ';') -- ^ Registered IANA format+ , sndData :: VCardData+ }+ -- | A value to uniquely identify the vCard. Please note well that this+ -- should be one of the registered IANA formats, but as of this time, this+ -- module does not support listing the UID type. E.g.,+ --+ -- > UID "19950401-080045-40000F192713-0052"+ | UID -> Uid { uidType :: Maybe (TypeS, ';')+ , uidData :: VCardString }+ -- | A website associated with the vCard entity. E.g.,+ --+ -- > URL "http://spearheaddev.com/"+ | URL -> Url { urlType :: TypeL URLType+ , urlAddr :: VCardString+ }+ -- | Describes the general intention of the vCard owner as to how+ -- accessible the included information should be. E.g.,+ --+ -- > Class ClassConfidential+ | CLASS -> Class Class+ -- | Specifies a public key or authentication certificate associated with+ -- the vCard entity. E.g.,+ --+ -- > Key "x509" (Binary "dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK")+ | KEY -> Key { keyType :: Maybe (TypeS, ';') -- ^ Registered IANA format+ , keyData :: VCardData+ }+ | EXTENSION s -> Extension VCardString+ | otherwise -> Other StringLn++-- | A breakdown of the vCard entity's name, corresponding, in sequence, to+-- Family Name, Given Name, Additional Names, Honorific Prefixes, and Honorific+-- Suffixes. E.g.,+--+-- > IndividualNames ["Schade"] ["Michael"] ["Anthony", "Fanetti"] [] ["Esq."]+data IndividualNames = IndividualNames { familyName :: NameSs+ , givenName :: NameSs+ , additionalNames :: NameSs+ , honorificPrefixes :: NameSs+ , honorificSuffixes :: NameSs+ }++data TZone = TzText ("VALUE=text:", StringLn)+ | TzInt (TimeZoneSE <| RE "$" |>)+++-- | Represents the various types or properties of an address.+data AddrType = AddrDomestic (StringME 'DOM|dom')+ | AddrInternational (StringME 'INTL|intl')+ | AddrPostal (StringME 'POSTAL|postal')+ | AddrParcel (StringME 'PARCEL|parcel')+ | AddrHome (StringME 'HOME|home')+ | AddrWork (StringME 'WORK|work')+ | AddrPreferred (StringME 'PREF|pref')++-- | Represents the various types or properties of a telephone number.+data TelType = TelHome "HOME"+ | TelMessage "MSG"+ | TelWork "WORK"+ | TelVoice "VOICE"+ | TelFax "FAX"+ | TelCell "CELL"+ | TelVideo "VIDEO"+ | TelPager "PAGER"+ | TelBBS "BBS"+ | TelModem "MODEM"+ | TelCar "CAR"+ | TelISDN "ISDN"+ | TelPCS "PCS"+ | TelMain "MAIN"+ | TelPreferred (StringME 'PREF|pref')++-- | Represents the various types or properties of a url.+data URLType = URLPreferred (StringME 'PREF|pref')+ | URLWork "WORK"+ | URLHome "HOME"++-- | Represents the various types or properties of an email address.+data EmailType = EmailInternet "INTERNET"+ | EmailX400 "X400"+ | EmailPreferred (StringME 'PREF|pref')+ | EmailWork "WORK"++-- | Represents the data associated with a vCard's Agent. This could be a URI+-- to such a vCard or the embedded contents of the vCard itself.+data AgentData = AgentURI ("VALUE=uri:", VCardString)+ | AgentVCard VCard++-- | Represents the various types of data that can be included in a vCard.+data VCardData = VURI ("VALUE=uri:", VCardString)+ | VBinary ("ENCODING=b", Maybe(';', TypeS), ':', WrappedEncoding )+ | VBase64 ("BASE64:", EOR, WrappedEncoding)++--type WrappedEncoding = [Line (StringLnP startsWithSpace)]+type WrappedEncoding = VCardString+++-- | Classifies the vCard's intended access level.+data Class = ClassPublic "PUBLIC"+ | ClassPrivate "PRIVATE"+ | ClassConfidential "CONFIDENTIAL"++-- Need to code base type StringESC. It takes a list of pairs.+-- Each pair represents a stopping condition.+-- If parser sees first component of tuple, it stops.+-- Second component is prefix to escape first component, so //, does not stop.+-- Pretty printer prefixes stopping components with escape sequence.+type VCardString = StringESCLn <| ('\\', ",:;") |>++type NameSs = [VCardString | ','] terminator ';|$'+++type TypeS = (typeRE, '=', CommaL VCardString)+type TypeL a = [(typeRE, '=', CommaL a) | ';'] terminator ':'+type CommaL a = [a|','] terminator Try (LitRE '[:;]')++|]+type CommonName = String+++colonsemiRE = RE "[:;]"+commasemiRE = RE "[,;]"+vcardRE = REd "VCARD|vCard" "VCARD"+typeRE = REd "TYPE|type" "TYPE"+++startsWithSpace s = case s of+ [] -> False+ ' ':s' -> True+ '\t':s' -> True+ '\v':s' -> True+ otherwise -> False++vcard_file_small = "Examples/data/VcardSmall.vcf"+vcard_file_large = "Examples/data/VcardSmall.vcf"+vcard_file = vcard_file_large++result n = do+ { (VCards rep, md) <- parseFile vcard_file+ ; return (Prelude.take n rep, fst md)+ }++test = do+ { (VCards rep, md) <- parseFile vcard_file+ ; return (fst md)+ }++entry_input = "N:Brush;A.J.;;;\r\n"+entry_result = entry_parseS entry_input++entry_input2 = "X-ABUID:3CC68169-6DC9-4457-94B3-B1B3C69E832A\\:ABPerson"+entry_result2 = entry_parseS entry_input2
@@ -0,0 +1,327 @@+{-# LANGUAGE TypeFamilies, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, ScopedTypeVariables, TypeSynonymInstances #-}++module VCardInfinite+ ( -- $doc+ VCard(..)+ , CommonName+ , IndividualNames(..)+ , VCardProperty(..)+ , AddrType(..)+ , TelType(..)+ , EmailType(..)+ , AgentData(..)+ , VCardData(..)+ , Class(..)+ ) where++import Data.List (intercalate)+import Data.Time (UTCTime, TimeZone, FormatTime, formatTime)++import Language.Pads.Padsc++-- Lines are delimited with carriage return/line-feed (control-M, newline) \r\n+-- Nested Vcards are separated by \n rather than \r\n++[pads|+-- KSF: Added to describe sequence of VCards+newtype VCards = VCards (partition [Line VCard] terminator EOF using windows)++-- KSF: moved IndividualNames and Common Name into VCardPropety because these attributes are not +-- guaranteed to be in a particular order.+data VCard = VCard ("BEGIN:", vcardRE, EOR, [Line Entry] terminator "END:", vcardRE)++data Entry = Entry { prefix :: Maybe ("item", Int, '.'),+ tag :: Tag, + sep :: StringME colonsemiRE, + property :: VCardProperty tag }++data Tag = VERSION | N | FN | NICKNAME | PHOTO | BDAY | ADR | LABEL+ | TEL | EMAIL | MAILER | TZ |GEO | TITLE | ROLE | LOGO | AGENT+ | ORG | CATEGORIES | NOTE | PRODID | REV | SORTSTRING "SORT-STRING"+ | SOUND | UID | URL | CLASS | KEY+ | EXTENSION ("X-", VCardString)+ | ITEM "item"+++data VCardProperty (tag :: Tag) = case tag of + -- | Version number of VCard file format+ VERSION -> Version (Int, '.', Int)++ -- | A breakdown of the vCard entity's name, as described by IndividualNames + | N -> Names IndividualNames++ -- | Formated name of the represented person+ --+ -- > CommonName "Mr. Michael A. F. Schade"+ | FN -> FName VCardString++ -- | A list of nicknames belonging to the VCard entity. E.g.,+ --+ -- > Nickname ["Mike", "Mikey"]+ | NICKNAME -> Nickname NameSs++ -- | A photo of the VCard entity. E.g.,+ --+ -- > Photo Nothing (URI "http://accentuate.us/smedia/images/michael.jpg")+ | PHOTO -> Photo VCardData++ -- | Specifies the birth date of the VCard entity. E.g.,+ --+ | BDAY -> Birthday { bdayType :: Maybe ("value=date:", ())+ , bdate :: DateFSE <| ("%Y-%m-%d", RE "$") |>+ }+ -- | A physical address associated with the vCard entity. E.g.,+ --+ -- > Address [AddrParcel, AddrPostal] "PO Box 935" "" "" "Fenton" "MO"+ -- > "63026" "USA"+ | ADR -> Address { addrType :: TypeL AddrType+ , poBox :: VCardString, ';'+ , extAddress :: VCardString, ';'+ , streetAddress :: VCardString, ';'+ , locality :: VCardString, ';' -- ^ City+ , region :: VCardString, ';' -- ^ State or Province+ , postalCode :: VCardString, ';'+ , countryName :: VCardString+ }+ -- | Formatted text about the delivery address. This is typically similar+ -- to the information in Address. E.g.,+ --+ -- > Label [AddrParcel, AddrPostal]+ -- > ["Michael Schade", "PO Box 935", "Fenton, MO 63026"]+ | LABEL -> Label { labelType :: TypeL AddrType+ , label :: VCardString+ }+ -- | A telephone number for the VCard entity, as well as a list of+ -- properties describing the telephone number. E.g.,+ --+ -- > Telephone [TelCell, TelPreferred] "+1-555-555-5555"+ | TEL -> Telephone { telType :: TypeL TelType+ , number :: VCardString+ }+ -- | An email address for the VCard entity, including a list of properties+ -- describing it. E.g.,+ --+ -- > Email [EmailInternet, EmailPreferred] "hackage@mschade.me"+ | EMAIL -> Email { emailType :: TypeL EmailType+ , emailAddr :: VCardString+ }+ -- | Specifies the mailing agent the vCard entity uses. E.g.,+ --+ -- > Mailer "MichaelMail 4.2" -- Not a real mailing agent, unfortunately :(+ | MAILER -> Mailer VCardString+ -- | Represents the time zone of the vCard entity. E.g.,+ --+ -- > TZ (hoursToTimeZone (-6))+ | TZ -> Tz TZone ++ -- | Relates to the global positioning of the vCard entity. The value is+ -- (latitude, longitude) and must be specified as decimal degrees,+ -- preferably to six decimal places.+ --+ -- > Geo (37.386013, -122.082932)+ | GEO -> Geo (Double, ';', Double)+ -- | The VCard entity's job title or other position. E.g.,+ --+ -- > Title "Co-Founder"+ | TITLE -> Title VCardString+ -- | Specifies the role associated with the title. E.g.,+ --+ -- > Role "Anything" -- For the co-founder, or+ -- > Role "Programmer" -- For someone the title "Research and Development"+ | ROLE -> Role VCardString+ -- | An image of the vCard entity's logo. This would typically relate to+ -- their organization. E.g.,+ --+ -- > Logo Nothing (URI "http://spearheaddev.com/smedia/images/logo-trans.png")+ | LOGO -> Logo VCardData+ -- | Indicates the vCard of an assistant or area administrator who is+ -- typically separately addressable. E.g.,+ --+ -- > Agent (AgentURI "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com")+ --+ -- or+ --+ -- > Agent (AgentVCard (VCard [ CommonName "James Q. Helpful"+ -- > , Email [EmailInternet] "j@spearheaddev.com"+ -- > ]))+ | AGENT -> Agent AgentData+ -- | The organization to which an entity belongs followed by organizational+ -- unit names. E.g.,+ --+ -- > Organization ["Spearhead Development, L.L.C.", "Executive"]+ | ORG -> Organization ([VCardString | ';'] terminator EOR)+ -- | General categories to describe the vCard entity. E.g.,+ --+ -- > Categories ["Internet", "Web Services", "Programmers"]+ | CATEGORIES -> Categories ([VCardString | ','] terminator EOR)+ -- | A general note about the vCard entity. E.g.,+ --+ -- > Note "Email is the absolute best contact method."+ | NOTE -> Note VCardString+ -- | Specifies the identifier of the product that created this vCard. E.g.,+ --+ -- > ProductId "-//ONLINE DIRECTORY//NONSGML Version 1//EN"+ --+ -- Please note well that, by RFC 2426 guidelines, \"implementations SHOULD+ -- use a method such as that specified for Formal Public Identifiers in ISO+ -- 9070 to assure that the text value is unique,\" but this module does not+ -- support that.+ | PRODID -> ProductId VCardString+ -- | Distinguishes the current revision from other renditions. E.g.,+ --+ -- > Revision $ UTCTime (fromGregorian 2011 04 16) (secondsToDiffTime 0)+ | REV -> Revision { revDate :: DateFSE <|("%Y-%m-%d", RE "T")|> + , revTime :: Maybe ('T', DateFSE <|("%H-%M-%SZ", RE "$")|>)+ } + -- | Provides a locale- or national-language-specific formatting of the+ -- formatted name based on the vCard entity's family or given name. E.g.,+ --+ -- > SortString "Schade"+ | SORTSTRING -> SortString VCardString+ -- | Specifies information in a digital sound format to annotate some+ -- aspect of the vCard. This is typically for the proper pronunciation of the+ -- vCard entity's name. E.g.,+ --+ -- > Sound "BASIC"+ -- > (URI "CID:JOHNQPUBLIC.part8.19960229T080000.xyzMail@host1.com")+ | SOUND -> Sound { sndType :: Maybe (TypeS, ';') -- ^ Registered IANA format+ , sndData :: VCardData+ }+ -- | A value to uniquely identify the vCard. Please note well that this+ -- should be one of the registered IANA formats, but as of this time, this+ -- module does not support listing the UID type. E.g.,+ --+ -- > UID "19950401-080045-40000F192713-0052"+ | UID -> Uid { uidType :: Maybe (TypeS, ';')+ , uidData :: VCardString }+ -- | A website associated with the vCard entity. E.g.,+ --+ -- > URL "http://spearheaddev.com/"+ | URL -> Url VCardString+ -- | Describes the general intention of the vCard owner as to how+ -- accessible the included information should be. E.g.,+ --+ -- > Class ClassConfidential+ | CLASS -> Class+ -- | Specifies a public key or authentication certificate associated with+ -- the vCard entity. E.g.,+ --+ -- > Key "x509" (Binary "dGhpcyBjb3VsZCBiZSAKbXkgY2VydGlmaWNhdGUK")+ | KEY -> Key { keyType :: Maybe (TypeS, ';') -- ^ Registered IANA format+ , keyData :: VCardData+ }+ | EXTENSION s -> Extension VCardString + | otherwise -> Other StringLn++-- | A breakdown of the vCard entity's name, corresponding, in sequence, to+-- Family Name, Given Name, Additional Names, Honorific Prefixes, and Honorific+-- Suffixes. E.g.,+--+-- > IndividualNames ["Schade"] ["Michael"] ["Anthony", "Fanetti"] [] ["Esq."]+data IndividualNames = IndividualNames { familyName :: NameSs+ , givenName :: NameSs+ , additionalNames :: NameSs+ , honorificPrefixes :: NameSs+ , honorificSuffixes :: NameSs+ }++data TZone = TzText ("VALUE=text:", StringLn)+ | TzInt (TimeZoneSE <| RE "$" |>)+++-- | Represents the various types or properties of an address.+data AddrType = AddrDomestic (StringME 'DOM|dom')+ | AddrInternational (StringME 'INTL|intl')+ | AddrPostal (StringME 'POSTAL|postal')+ | AddrParcel (StringME 'PARCEL|parcel')+ | AddrHome (StringME 'HOME|home')+ | AddrWork (StringME 'WORK|work')+ | AddrPreferred (StringME 'PREF|pref')++-- | Represents the various types or properties of a telephone number.+data TelType = TelHome "HOME"+ | TelMessage "MSG"+ | TelWork "WORK"+ | TelVoice "VOICE"+ | TelFax "FAX"+ | TelCell "CELL"+ | TelVideo "VIDEO"+ | TelPager "PAGER"+ | TelBBS "BBS"+ | TelModem "MODEM"+ | TelCar "CAR"+ | TelISDN "ISDN"+ | TelPCS "PCS"+ | TelPreferred (StringME 'PREF|pref')+++-- | Represents the various types or properties of an email address.+data EmailType = EmailInternet "INTERNET"+ | EmailX400 "X400"+ | EmailPreferred (StringME 'PREF|pref')+ | EmailWork "WORK"++-- | Represents the data associated with a vCard's Agent. This could be a URI+-- to such a vCard or the embedded contents of the vCard itself.+data AgentData = AgentURI ("VALUE=uri:", VCardString)+ | AgentVCard VCard++-- | Represents the various types of data that can be included in a vCard.+data VCardData = VURI ("VALUE=uri:", VCardString) + | VBinary ("ENCODING=b", Maybe(';', TypeS), ':', WrappedEncoding )+ | VBase64 ("BASE64:", WrappedEncoding)++type WrappedEncoding = [Line (StringLnP startsWithSpace)]+++-- | Classifies the vCard's intended access level.+data Class = ClassPublic "PUBLIC"+ | ClassPrivate "PRIVATE"+ | ClassConfidential "CONFIDENTIAL"++-- Need to code base type StringESC. It takes a list of pairs.+-- Each pair represents a stopping condition.+-- If parser sees first component of tuple, it stops.+-- Second component is prefix to escape first component, so //, does not stop.+-- Pretty printer prefixes stopping components with escape sequence.+type VCardString = StringESCLn <| ('\\', ",:;") |>++type NameSs = [VCardString | ','] terminator ';|$'+++type TypeS = (typeRE, '=', [VCardString|','] terminator Try (LitRE '[:;]'))+--type TypeL a = [(typeRE, '=', [a|','] terminator Try (Lit ";")) | ';'] terminator ':'+--type TypeL a = [(typeRE, '=', CommaL a) | ';'] terminator ':'+--type TypeL a = [(typeRE, '=', a) | ';'] terminator ':'+type TypeL a = [(typeRE, '=', CommaL a) | ';'] terminator ':'+type CommaL a = [a|','] terminator Try (Lit ";")++|]+type CommonName = String+++colonsemiRE = RE "[:;]"+commasemiRE = RE "[,;]"+vcardRE = REd "VCARD|vCard" "VCARD"+typeRE = REd "TYPE|type" "TYPE"+++startsWithSpace s = case s of + [] -> False+ ' ':s' -> True+ '\t':s' -> True+ '\v':s' -> True+ otherwise -> False++vcard_file = "Examples/data/VcardSmall.vcf"++result n = do + { (VCards rep, md) <- parseFile vcard_file+ ; return (Prelude.take n rep, fst md)+ } ++entry_input = "N:Brush;A.J.;;;\r\n"+entry_result = entry_parseS entry_input++entry_input2 = "X-ABUID:3CC68169-6DC9-4457-94B3-B1B3C69E832A\\:ABPerson"+entry_result2 = entry_parseS entry_input2
@@ -0,0 +1,24 @@+This directory contains data for example programs.++For Examples/First.hs+ Examples/data/test_file++For Examples/AI.hs+ Examples/data/ai.3000+ Examples/data/ai.big++For Examples/Binary.hs+ Examples/data/binary -- Small input test file+ Call Detail Records+ Examples/data/a2b.c -- C program to convert ascii records to binary+ -- To compile: cc -o a2b a2b.c+ -- To run: a2b < calls10.a > calls10.b+ Examples/data/calls10.a, -- ASCII call detail records+ Examples/data/calls10.b, -- Corresponding binary records+ + Binary base type tseting+ Examples/data/genBin.c, -- C program to convert ascii records to binary+ -- To compile: cc -o genBin binTest.a+ -- To run: genBin < binTest.a > binTest.b+ Examples/data/binTest.a, + Examples/data/binTest.b
@@ -0,0 +1,34 @@+#include <stdio.h>++/* Reads ascii call detail records from stdin.+ * Writes scampRec binary call detail records on stdout.+ */++typedef struct+{+ int onpa, obase;+ int dnpa, dbase;+ int con;+ int dur; +} scampRec_t;++++int readAscii(FILE *in, scampRec_t *r){+ int success = fscanf(in, "%d %d %d %d %d %d\n",+ &(r->onpa), &(r->obase), + &(r->dnpa), &(r->dbase),+ &(r->con), &(r->dur)); + return success;+}++void writeBinary(FILE *out, scampRec_t *r){+ fwrite(r, sizeof(scampRec_t), 1, out);+}++int main(){+ scampRec_t current;+ while (readAscii(stdin, ¤t) != EOF)+ writeBinary(stdout, ¤t);+ return 0;+}
@@ -0,0 +1,3001 @@+207.136.97.49 - - [15/Oct/1997:18:46:51 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+207.136.97.49 - - [15/Oct/1997:18:46:51 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+207.136.97.49 - - [15/Oct/1997:18:46:52 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+207.136.97.49 - - [15/Oct/1997:18:46:52 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+208.196.124.26 - - [15/Oct/1997:18:46:55 -0700] "GET /candatop.html HTTP/1.0" 200 10629+208.196.124.26 - - [15/Oct/1997:18:46:57 -0700] "GET /images/done.gif HTTP/1.0" 200 4785+208.196.124.26 - - [15/Oct/1997:18:47:01 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237+208.196.124.26 - - [15/Oct/1997:18:47:02 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836+208.196.124.26 - - [15/Oct/1997:18:47:05 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833+208.196.124.26 - - [15/Oct/1997:18:47:08 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638+208.196.124.26 - - [15/Oct/1997:18:47:09 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429+208.196.124.26 - - [15/Oct/1997:18:47:09 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352+128.200.68.71 - - [15/Oct/1997:18:47:11 -0700] "GET /amnesty/usalinks.html HTTP/1.0" 200 10329+208.196.124.26 - - [15/Oct/1997:18:47:11 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859+128.200.68.71 - - [15/Oct/1997:18:47:12 -0700] "GET /amnesty/images/ai_cand1.gif HTTP/1.0" 200 6328+128.200.68.71 - - [15/Oct/1997:18:47:12 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+128.200.68.71 - - [15/Oct/1997:18:47:13 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+208.196.124.26 - - [15/Oct/1997:18:47:14 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903+128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+128.200.68.71 - - [15/Oct/1997:18:47:15 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+128.200.68.71 - - [15/Oct/1997:18:47:16 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+!! BAD LINE !!+208.196.124.26 - - [15/Oct/1997:18:47:16 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+128.200.68.71 - - [15/Oct/1997:18:47:19 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+208.196.124.26 - - [15/Oct/1997:18:47:21 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625+208.196.124.26 - - [15/Oct/1997:18:47:23 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+208.196.124.26 - - [15/Oct/1997:18:47:23 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+208.196.124.26 - - [15/Oct/1997:18:47:24 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+208.196.124.26 - - [15/Oct/1997:18:47:32 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+208.196.124.26 - - [15/Oct/1997:18:47:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+128.200.68.71 - - [15/Oct/1997:18:48:01 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902+128.200.68.71 - - [15/Oct/1997:18:48:02 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509+128.200.68.71 - - [15/Oct/1997:18:48:02 -0700] "GET /amnesty/images/whobut.gif HTTP/1.0" 200 505+128.200.68.71 - - [15/Oct/1997:18:48:04 -0700] "GET /amnesty/images/aalogo.gif HTTP/1.0" 200 15293+128.200.68.71 - - [15/Oct/1997:18:48:05 -0700] "GET /amnesty/images/whatbut.gif HTTP/1.0" 200 526+128.200.68.71 - - [15/Oct/1997:18:48:05 -0700] "GET /amnesty/images/where.gif HTTP/1.0" 200 605+206.175.186.71 - - [15/Oct/1997:18:48:07 -0700] "GET /amnesty/immigr.html HTTP/1.0" 200 11284+128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+128.200.68.71 - - [15/Oct/1997:18:48:08 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+128.200.68.71 - - [15/Oct/1997:18:48:09 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+128.200.68.71 - - [15/Oct/1997:18:48:35 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629+128.200.68.71 - - [15/Oct/1997:18:48:36 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785+128.200.68.71 - - [15/Oct/1997:18:48:37 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638+128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352+128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859+128.200.68.71 - - [15/Oct/1997:18:48:38 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+128.200.68.71 - - [15/Oct/1997:18:48:39 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625+128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833+128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429+128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237+128.200.68.71 - - [15/Oct/1997:18:48:40 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836+128.200.68.71 - - [15/Oct/1997:18:48:41 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+128.200.68.71 - - [15/Oct/1997:18:48:44 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903+128.200.68.71 - - [15/Oct/1997:18:49:17 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+128.200.68.71 - - [15/Oct/1997:18:49:17 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+128.200.68.71 - - [15/Oct/1997:18:49:19 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+128.200.68.71 - - [15/Oct/1997:18:49:20 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+128.200.68.71 - - [15/Oct/1997:18:49:21 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+148.4.61.168 - - [15/Oct/1997:18:49:22 -0700] "GET / HTTP/1.0" 200 3082+128.200.68.71 - - [15/Oct/1997:18:49:22 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+128.200.68.71 - - [15/Oct/1997:18:49:23 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+128.200.68.71 - - [15/Oct/1997:18:49:24 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+128.200.68.71 - - [15/Oct/1997:18:49:24 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+148.4.61.168 - - [15/Oct/1997:18:49:24 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+128.200.68.71 - - [15/Oct/1997:18:49:25 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+128.200.68.71 - - [15/Oct/1997:18:49:25 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+148.4.61.168 - - [15/Oct/1997:18:49:28 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+128.200.68.71 - - [15/Oct/1997:18:49:30 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+128.200.68.71 - - [15/Oct/1997:18:49:31 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+148.4.61.168 - - [15/Oct/1997:18:49:37 -0700] "GET /joinai.html HTTP/1.0" 200 4054+148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+148.4.61.168 - - [15/Oct/1997:18:49:38 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+148.4.61.168 - - [15/Oct/1997:18:49:39 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+148.4.61.168 - - [15/Oct/1997:18:49:39 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+148.4.61.168 - - [15/Oct/1997:18:49:41 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+148.4.61.168 - - [15/Oct/1997:18:51:48 -0700] "POST /scripts/mailform/aimember@aiusa.org/confirm HTTP/1.0" 200 553+148.4.61.168 - - [15/Oct/1997:18:51:49 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+148.4.61.168 - - [15/Oct/1997:18:51:59 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+148.4.61.168 - - [15/Oct/1997:18:52:00 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+148.4.61.168 - - [15/Oct/1997:18:52:33 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629+148.4.61.168 - - [15/Oct/1997:18:52:35 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237+148.4.61.168 - - [15/Oct/1997:18:52:35 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859+148.4.61.168 - - [15/Oct/1997:18:52:37 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836+148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638+148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833+148.4.61.168 - - [15/Oct/1997:18:52:38 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429+148.4.61.168 - - [15/Oct/1997:18:52:39 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352+148.4.61.168 - - [15/Oct/1997:18:52:40 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625+148.4.61.168 - - [15/Oct/1997:18:52:41 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+148.4.61.168 - - [15/Oct/1997:18:52:42 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509+148.4.61.168 - - [15/Oct/1997:18:52:42 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903+148.4.61.168 - - [15/Oct/1997:18:52:43 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785+148.4.61.168 - - [15/Oct/1997:18:53:14 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+148.4.61.168 - - [15/Oct/1997:18:53:14 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+148.4.61.168 - - [15/Oct/1997:18:53:15 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+148.4.61.168 - - [15/Oct/1997:18:53:16 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+148.4.61.168 - - [15/Oct/1997:18:53:16 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+148.4.61.168 - - [15/Oct/1997:18:53:17 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+208.151.41.69 - - [15/Oct/1997:18:53:29 -0700] "GET /country/balkans HTTP/1.0" 301 196+128.200.68.71 - - [15/Oct/1997:18:53:30 -0700] "GET /amnesty/about/history.html HTTP/1.0" 200 10342+128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/about/images/airmail2.jpg HTTP/1.0" 200 7820+128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/about/images/coverbut.gif HTTP/1.0" 200 400+128.200.68.71 - - [15/Oct/1997:18:53:31 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+208.151.41.69 - - [15/Oct/1997:18:53:31 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/about/images/backtono.gif HTTP/1.0" 200 2367+128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/about/images/sagan4.gif HTTP/1.0" 200 3596+128.200.68.71 - - [15/Oct/1997:18:53:32 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786+128.200.68.71 - - [15/Oct/1997:18:53:33 -0700] "GET /amnesty/about/images/masthd3.gif HTTP/1.0" 200 33250+128.200.68.71 - - [15/Oct/1997:18:53:33 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+208.151.41.69 - - [15/Oct/1997:18:53:33 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+208.151.41.69 - - [15/Oct/1997:18:53:35 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+208.151.41.69 - - [15/Oct/1997:18:53:35 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+208.151.41.69 - - [15/Oct/1997:18:53:36 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+208.151.41.69 - - [15/Oct/1997:18:53:37 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+208.151.41.69 - - [15/Oct/1997:18:53:38 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+207.228.67.219 - - [15/Oct/1997:18:53:47 -0700] "GET / HTTP/1.0" 200 3082+207.228.67.219 - - [15/Oct/1997:18:53:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+207.228.67.219 - - [15/Oct/1997:18:53:55 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+128.200.68.71 - - [15/Oct/1997:18:54:03 -0700] "GET /amnesty/feats/wamphoto.html HTTP/1.0" 200 6567+128.200.68.71 - - [15/Oct/1997:18:54:04 -0700] "GET /amnesty/images/opencuf2.jpg HTTP/1.0" 200 2581+207.228.67.219 - - [15/Oct/1997:18:54:04 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+128.200.68.71 - - [15/Oct/1997:18:54:05 -0700] "GET /amnesty/images/wamwere.gif HTTP/1.0" 200 19858+207.228.67.219 - - [15/Oct/1997:18:54:08 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483+207.228.67.219 - - [15/Oct/1997:18:54:10 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498+207.228.67.219 - - [15/Oct/1997:18:54:17 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+207.228.67.219 - - [15/Oct/1997:18:54:24 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848+207.228.67.219 - - [15/Oct/1997:18:54:32 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585+128.200.68.71 - - [15/Oct/1997:18:54:35 -0700] "GET /amnesty/ann-rpt.html HTTP/1.0" 200 1899+207.228.67.219 - - [15/Oct/1997:18:54:40 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+207.228.67.219 - - [15/Oct/1997:18:54:58 -0700] "GET /comm/honor2.html HTTP/1.0" 200 10981+128.200.68.71 - - [15/Oct/1997:18:55:01 -0700] "GET /amnesty/ar-sum.html HTTP/1.0" 200 27608+128.200.68.71 - - [15/Oct/1997:18:55:07 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+207.228.67.219 - - [15/Oct/1997:18:55:08 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517+207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/jagger3.jpg HTTP/1.0" 200 4864+207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/stew3.jpg HTTP/1.0" 200 5558+207.228.67.219 - - [15/Oct/1997:18:55:17 -0700] "GET /comm/images/people/wallace3.jpg HTTP/1.0" 200 5348+207.228.67.219 - - [15/Oct/1997:18:55:36 -0700] "GET /comm/images/people/berman3.jpg HTTP/1.0" 200 4705+207.228.67.219 - - [15/Oct/1997:18:55:40 -0700] "GET /comm/images/people/bailey3.jpg HTTP/1.0" 200 4565+207.228.67.219 - - [15/Oct/1997:18:55:41 -0700] "GET /comm/images/people/herbert3.jpg HTTP/1.0" 200 4819+207.228.67.219 - - [15/Oct/1997:18:55:43 -0700] "GET /comm/images/spot05.gif HTTP/1.0" 200 8192+207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:55:54 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+207.228.67.219 - - [15/Oct/1997:18:55:57 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+207.228.67.219 - - [15/Oct/1997:18:55:59 -0700] "GET /home.html HTTP/1.0" 200 17233+207.228.67.219 - - [15/Oct/1997:18:55:59 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:01 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+207.228.67.219 - - [15/Oct/1997:18:56:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:03 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+207.228.67.219 - - [15/Oct/1997:18:56:04 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+207.228.67.219 - - [15/Oct/1997:18:56:06 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:07 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+207.228.67.219 - - [15/Oct/1997:18:56:07 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:08 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:08 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+207.228.67.219 - - [15/Oct/1997:18:56:09 -0700] "GET /images/countbut.gif HTTP/1.0" 304 -+207.228.67.219 - - [15/Oct/1997:18:56:11 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+207.228.67.219 - - [15/Oct/1997:18:56:12 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+207.228.67.219 - - [15/Oct/1997:18:56:12 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+207.228.67.219 - - [15/Oct/1997:18:56:15 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+207.228.67.219 - - [15/Oct/1997:18:56:33 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+128.200.68.71 - - [15/Oct/1997:18:56:46 -0700] "GET /amnesty/mandate.html HTTP/1.0" 200 21981+148.4.61.168 - - [15/Oct/1997:18:56:55 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483+148.4.61.168 - - [15/Oct/1997:18:56:56 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498+148.4.61.168 - - [15/Oct/1997:18:56:56 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+148.4.61.168 - - [15/Oct/1997:18:56:57 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848+148.4.61.168 - - [15/Oct/1997:18:56:57 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+148.4.61.168 - - [15/Oct/1997:18:57:00 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585+148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /home.html HTTP/1.0" 200 17233+148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+148.4.61.168 - - [15/Oct/1997:18:57:41 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+148.4.61.168 - - [15/Oct/1997:18:57:42 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+148.4.61.168 - - [15/Oct/1997:18:57:43 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+148.4.61.168 - - [15/Oct/1997:18:57:45 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+148.4.61.168 - - [15/Oct/1997:18:57:46 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+148.4.61.168 - - [15/Oct/1997:18:57:47 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+207.67.28.158 - - [15/Oct/1997:18:58:12 -0700] "GET /refugee HTTP/1.0" 301 188+207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836+207.67.28.158 - - [15/Oct/1997:18:58:16 -0700] "GET /images/turqbut.gif HTTP/1.0" 200 903+207.67.28.158 - - [15/Oct/1997:18:58:18 -0700] "GET /refugee/ HTTP/1.0" 200 18751+207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/morinfox.gif HTTP/1.0" 200 2056+207.67.28.158 - - [15/Oct/1997:18:58:23 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+148.4.61.168 - - [15/Oct/1997:18:58:50 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+148.4.61.168 - - [15/Oct/1997:18:58:54 -0700] "GET /about.html HTTP/1.0" 200 6902+148.4.61.168 - - [15/Oct/1997:18:58:55 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+148.4.61.168 - - [15/Oct/1997:18:58:55 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+148.4.61.168 - - [15/Oct/1997:18:58:56 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+148.4.61.168 - - [15/Oct/1997:18:58:57 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+148.4.61.168 - - [15/Oct/1997:18:58:57 -0700] "GET /images/where.gif HTTP/1.0" 200 605+148.4.61.168 - - [15/Oct/1997:18:59:00 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+136.168.101.17 - - [15/Oct/1997:18:59:09 -0700] "GET / HTTP/1.0" 200 3082+207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+207.67.28.158 - - [15/Oct/1997:18:59:09 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+207.67.28.158 - - [15/Oct/1997:18:59:10 -0700] "GET /home.html HTTP/1.0" 200 17233+136.168.101.17 - - [15/Oct/1997:18:59:10 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+207.67.28.158 - - [15/Oct/1997:18:59:11 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+207.67.28.158 - - [15/Oct/1997:18:59:12 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+136.168.101.17 - - [15/Oct/1997:18:59:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+207.67.28.158 - - [15/Oct/1997:18:59:13 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+207.67.28.158 - - [15/Oct/1997:18:59:13 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+207.67.28.158 - - [15/Oct/1997:18:59:15 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+207.67.28.158 - - [15/Oct/1997:18:59:17 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+24.64.22.142 - - [15/Oct/1997:18:59:18 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527+207.67.28.158 - - [15/Oct/1997:18:59:18 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+207.67.28.158 - - [15/Oct/1997:18:59:18 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368+24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380+24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363+24.64.22.142 - - [15/Oct/1997:18:59:19 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399+207.67.28.158 - - [15/Oct/1997:18:59:19 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+24.64.22.142 - - [15/Oct/1997:18:59:20 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317+24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329+24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384+24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352+24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366+24.64.22.142 - - [15/Oct/1997:18:59:21 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383+207.67.28.158 - - [15/Oct/1997:18:59:21 -0700] "GET /write.html HTTP/1.0" 200 9408+24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352+24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432+24.64.22.142 - - [15/Oct/1997:18:59:22 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403+207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+207.67.28.158 - - [15/Oct/1997:18:59:22 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166+24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592+24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344+24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359+24.64.22.142 - - [15/Oct/1997:18:59:23 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352+207.67.28.158 - - [15/Oct/1997:18:59:23 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+207.67.28.158 - - [15/Oct/1997:18:59:25 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /about.html HTTP/1.0" 200 6902+136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+136.168.101.17 - - [15/Oct/1997:18:59:26 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+136.168.101.17 - - [15/Oct/1997:18:59:27 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+136.168.101.17 - - [15/Oct/1997:18:59:27 -0700] "GET /images/where.gif HTTP/1.0" 200 605+136.168.101.17 - - [15/Oct/1997:18:59:28 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+136.168.101.17 - - [15/Oct/1997:18:59:29 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+136.168.101.17 - - [15/Oct/1997:18:59:30 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/iran.html HTTP/1.0" 200 8412+24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/iran.jpg HTTP/1.0" 200 3240+24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/irnflag.gif HTTP/1.0" 200 2273+24.64.22.142 - - [15/Oct/1997:18:59:35 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202+207.67.28.158 - - [15/Oct/1997:19:00:19 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+207.67.28.158 - - [15/Oct/1997:19:00:19 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887+207.67.28.158 - - [15/Oct/1997:19:00:20 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308+24.64.22.142 - - [15/Oct/1997:19:00:28 -0700] "GET /amnesty/mideast/index.html HTTP/1.0" 200 3104+24.64.22.142 - - [15/Oct/1997:19:00:29 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682+24.64.22.142 - - [15/Oct/1997:19:00:35 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216+148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /group.html HTTP/1.0" 200 8575+148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161+148.4.61.168 - - [15/Oct/1997:19:00:59 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471+148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+148.4.61.168 - - [15/Oct/1997:19:01:00 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+148.4.61.168 - - [15/Oct/1997:19:01:01 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013+148.4.61.168 - - [15/Oct/1997:19:01:01 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399+148.4.61.168 - - [15/Oct/1997:19:01:02 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257+148.4.61.168 - - [15/Oct/1997:19:01:06 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+148.4.61.168 - - [15/Oct/1997:19:01:07 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430+24.64.22.142 - - [15/Oct/1997:19:01:08 -0700] "GET /amnesty/mideast/counfram.html HTTP/1.0" 200 1145+24.64.22.142 - - [15/Oct/1997:19:01:09 -0700] "GET /amnesty/mideast/algeria.html HTTP/1.0" 200 7945+24.64.22.142 - - [15/Oct/1997:19:01:10 -0700] "GET /amnesty/mideast/algeria.jpg HTTP/1.0" 200 5485+24.64.22.142 - - [15/Oct/1997:19:01:10 -0700] "GET /amnesty/mideast/algflag.gif HTTP/1.0" 200 1902+204.162.96.92 - - [15/Oct/1997:19:01:14 -0700] "GET /robots.txt HTTP/1.0" 404 163+204.162.96.92 - - [15/Oct/1997:19:01:25 -0700] "GET /education/ HTTP/1.0" 200 9100+207.67.28.158 - - [15/Oct/1997:19:01:31 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+207.67.28.158 - - [15/Oct/1997:19:01:34 -0700] "GET /urgact/newslett.html HTTP/1.0" 200 26074+207.67.28.158 - - [15/Oct/1997:19:02:12 -0700] "GET /urgact/index.html HTTP/1.0" 200 8283+207.67.28.158 - - [15/Oct/1997:19:02:40 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+207.67.28.158 - - [15/Oct/1997:19:02:41 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+207.67.28.158 - - [15/Oct/1997:19:02:42 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+207.67.28.158 - - [15/Oct/1997:19:02:42 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+207.67.28.158 - - [15/Oct/1997:19:02:48 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+207.67.28.158 - - [15/Oct/1997:19:02:53 -0700] "GET /welcome.html HTTP/1.0" 200 4731+207.67.28.158 - - [15/Oct/1997:19:02:55 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+207.67.28.158 - - [15/Oct/1997:19:02:55 -0700] "GET /images/never.gif HTTP/1.0" 200 914+207.67.28.158 - - [15/Oct/1997:19:02:56 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924+207.67.28.158 - - [15/Oct/1997:19:03:00 -0700] "GET /images/commit.gif HTTP/1.0" 200 190+207.67.28.158 - - [15/Oct/1997:19:03:00 -0700] "GET /images/your.gif HTTP/1.0" 200 951+207.67.28.158 - - [15/Oct/1997:19:03:01 -0700] "GET /images/rights.gif HTTP/1.0" 200 938+207.67.28.158 - - [15/Oct/1997:19:03:02 -0700] "GET /images/can.gif HTTP/1.0" 200 946+207.67.28.158 - - [15/Oct/1997:19:03:04 -0700] "GET /images/a.gif HTTP/1.0" 200 865+207.67.28.158 - - [15/Oct/1997:19:03:04 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882+207.67.28.158 - - [15/Oct/1997:19:03:05 -0700] "GET /images/differ.gif HTTP/1.0" 200 191+204.162.96.93 - - [15/Oct/1997:19:03:06 -0700] "GET /amnesty/regions/maregcon.html HTTP/1.0" 200 1304+207.67.28.158 - - [15/Oct/1997:19:03:06 -0700] "GET /images/canred.gif HTTP/1.0" 200 311+207.67.28.158 - - [15/Oct/1997:19:03:08 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+148.4.61.168 - - [15/Oct/1997:19:03:09 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+148.4.61.168 - - [15/Oct/1997:19:03:10 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+207.67.28.158 - - [15/Oct/1997:19:03:11 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157+148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+148.4.61.168 - - [15/Oct/1997:19:03:11 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+148.4.61.168 - - [15/Oct/1997:19:03:12 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+207.67.28.158 - - [15/Oct/1997:19:03:13 -0700] "GET /images/it.gif HTTP/1.0" 200 170+148.4.61.168 - - [15/Oct/1997:19:03:13 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+148.4.61.168 - - [15/Oct/1997:19:03:13 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+148.4.61.168 - - [15/Oct/1997:19:03:14 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+207.67.28.158 - - [15/Oct/1997:19:03:16 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591+207.67.28.158 - - [15/Oct/1997:19:03:17 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581+148.4.61.168 - - [15/Oct/1997:19:03:17 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+207.67.28.158 - - [15/Oct/1997:19:03:19 -0700] "GET /images/human.gif HTTP/1.0" 200 155+207.67.28.158 - - [15/Oct/1997:19:03:27 -0700] "GET /postcard/welact.html HTTP/1.0" 200 4640+207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/joinbut.gif HTTP/1.0" 200 409+207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/w.gif HTTP/1.0" 200 565+207.67.28.158 - - [15/Oct/1997:19:03:29 -0700] "GET /postcard/images/welbut.gif HTTP/1.0" 200 600+207.67.28.158 - - [15/Oct/1997:19:03:30 -0700] "GET /postcard/images/letbut.gif HTTP/1.0" 200 517+207.67.28.158 - - [15/Oct/1997:19:03:31 -0700] "GET /postcard/images/aiusabut.gif HTTP/1.0" 200 591+207.67.28.158 - - [15/Oct/1997:19:03:41 -0700] "GET /postcard/images/wombarb9.gif HTTP/1.0" 200 20647+148.4.61.168 - - [15/Oct/1997:19:04:34 -0700] "GET /members.html HTTP/1.0" 200 1501+148.4.61.168 - - [15/Oct/1997:19:04:35 -0700] "GET /images/memlogo.gif HTTP/1.0" 200 7872+148.4.61.168 - - [15/Oct/1997:19:04:49 -0700] "GET /members/index.html HTTP/1.0" 401 350+148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+148.4.61.168 - - [15/Oct/1997:19:05:15 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+148.4.61.168 - - [15/Oct/1997:19:05:20 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+148.4.61.168 - - [15/Oct/1997:19:05:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+152.163.207.138 - - [15/Oct/1997:19:05:54 -0700] "GET / HTTP/1.0" 200 3082+152.163.207.138 - - [15/Oct/1997:19:06:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+152.163.207.138 - - [15/Oct/1997:19:06:03 -0700] "GET /images/spot5.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:06:52 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+152.163.207.138 - - [15/Oct/1997:19:06:56 -0700] "GET /images/pandnlog.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:06:59 -0700] "GET /images/ganbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:00 -0700] "GET /images/campbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:02 -0700] "GET /images/deathbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:02 -0700] "GET /images/groupbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:03 -0700] "GET /images/dot.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:04 -0700] "GET /images/uabut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:05 -0700] "GET /images/refbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:07 -0700] "GET /images/ncasebut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:08 -0700] "GET /images/lgbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:09 -0700] "GET /images/educbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:09 -0700] "GET /images/healbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:11 -0700] "GET /images/legalbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:12 -0700] "GET /images/womenbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:12 -0700] "GET /images/wordo35d.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:14 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:15 -0700] "GET /images/penhand3.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:16 -0700] "GET /images/kids3.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:16 -0700] "GET /images/womland2.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:18 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:21 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:22 -0700] "GET /images/homebut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:07:23 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:04 -0700] "GET /candatop.html HTTP/1.0" 200 10629+152.163.207.138 - - [15/Oct/1997:19:08:08 -0700] "GET /images/candalog.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:09 -0700] "GET /images/done.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:11 -0700] "GET /images/hasene2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:11 -0700] "GET /images/rally4.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/reddash2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/refrun1.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:13 -0700] "GET /images/reyes.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:14 -0700] "GET /images/kids5.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:15 -0700] "GET /images/nigpost1.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:16 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:17 -0700] "GET /images/howbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:08:19 -0700] "GET /images/turkboy.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:09:18 -0700] "GET / HTTP/1.0" 200 -+206.175.189.221 - - [15/Oct/1997:19:09:29 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+206.175.189.221 - - [15/Oct/1997:19:09:32 -0700] "GET /images/spot5.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:09:33 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+152.163.207.138 - - [15/Oct/1997:19:09:36 -0700] "GET /group.html HTTP/1.0" 200 8575+152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/can1_2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/goldfla2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:42 -0700] "GET /images/grncndl.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:44 -0700] "GET /images/04candle.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:44 -0700] "GET /images/canfuz1.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:47 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:53 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:54 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:58 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:09:58 -0700] "GET /images/evenbut.gif HTTP/1.0" 304 -+136.168.101.19 - - [15/Oct/1997:19:10:07 -0700] "GET / HTTP/1.0" 200 3082+136.168.101.19 - - [15/Oct/1997:19:10:08 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+136.168.101.19 - - [15/Oct/1997:19:10:09 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+206.175.189.221 - - [15/Oct/1997:19:10:10 -0700] "GET /write.html HTTP/1.0" 200 9408+206.175.189.221 - - [15/Oct/1997:19:10:12 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166+206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:10:13 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:10:15 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:10:16 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:10:16 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+136.168.101.19 - - [15/Oct/1997:19:10:28 -0700] "GET /about.html HTTP/1.0" 200 6902+136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+136.168.101.19 - - [15/Oct/1997:19:10:29 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+136.168.101.19 - - [15/Oct/1997:19:10:30 -0700] "GET /images/where.gif HTTP/1.0" 200 605+136.168.101.19 - - [15/Oct/1997:19:10:31 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+136.168.101.19 - - [15/Oct/1997:19:10:32 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+136.168.101.19 - - [15/Oct/1997:19:10:32 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+152.163.207.138 - - [15/Oct/1997:19:10:39 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:11:12 -0700] "GET /joinai.html HTTP/1.0" 200 4054+206.175.189.221 - - [15/Oct/1997:19:11:14 -0700] "GET /weeklyua.html HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:11:16 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:11:16 -0700] "GET /images/linebrn.gif HTTP/1.0" 304 -+206.175.189.221 - - [15/Oct/1997:19:11:16 -0700] "GET /images/logo2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:11:37 -0700] "GET /home.html HTTP/1.0" 200 17233+152.163.207.138 - - [15/Oct/1997:19:11:43 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+152.163.207.138 - - [15/Oct/1997:19:11:47 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:11:56 -0700] "GET /ainews.html HTTP/1.0" 200 13435+152.163.207.138 - - [15/Oct/1997:19:12:08 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:10 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:12 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:12 -0700] "GET /images/refhand4.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:14 -0700] "GET /images/countbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:16 -0700] "GET /images/netbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:16 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:17 -0700] "GET /images/joinbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:19 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:20 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:12:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:09 -0700] "GET /feats/weij.html HTTP/1.0" 200 6121+152.163.205.106 - - [15/Oct/1997:19:13:21 -0700] "GET /casework/fw.html HTTP/1.0" 304 -+152.163.205.106 - - [15/Oct/1997:19:13:24 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 304 -+152.163.205.106 - - [15/Oct/1997:19:13:24 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:33 -0700] "GET /asa/china/ HTTP/1.0" 200 18000+152.163.207.138 - - [15/Oct/1997:19:13:37 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336+152.163.207.138 - - [15/Oct/1997:19:13:51 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:53 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+152.163.207.138 - - [15/Oct/1997:19:13:54 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:57 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:57 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:13:58 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122+152.163.207.138 - - [15/Oct/1997:19:13:59 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:14:01 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983+152.163.205.106 - - [15/Oct/1997:19:14:09 -0700] "GET /casework/fwq&a.html HTTP/1.0" 200 6329+152.163.207.138 - - [15/Oct/1997:19:14:12 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:14:13 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411+152.163.207.138 - - [15/Oct/1997:19:14:15 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:14:15 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:14:16 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794+152.163.207.138 - - [15/Oct/1997:19:14:18 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202+152.163.207.138 - - [15/Oct/1997:19:14:19 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648+152.163.207.138 - - [15/Oct/1997:19:14:27 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:14:33 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:15:55 -0700] "GET /asa/china/images/blue.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:15:57 -0700] "GET /asa/china/tibet.html HTTP/1.0" 200 8882+152.163.205.106 - - [15/Oct/1997:19:16:03 -0700] "GET /casework/fw1.html HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:16:04 -0700] "GET /asa/china/images/cgyatso2.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:16:04 -0700] "GET /asa/china/images/mainmenu.gif HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:16:06 -0700] "GET /asa/china/images/cohen.jpg HTTP/1.0" 304 -+152.163.207.138 - - [15/Oct/1997:19:16:55 -0700] "GET /asa/china/TRANS.GIF HTTP/1.0" 404 172+152.163.207.138 - - [15/Oct/1997:19:16:55 -0700] "GET /asa/china/cando.html HTTP/1.0" 200 8129+152.163.207.138 - - [15/Oct/1997:19:17:00 -0700] "GET /asa/china/images/mailme.gif HTTP/1.0" 200 14893+136.168.221.19 - - [15/Oct/1997:19:17:10 -0700] "GET / HTTP/1.0" 200 3082+136.168.221.19 - - [15/Oct/1997:19:17:12 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+136.168.221.19 - - [15/Oct/1997:19:17:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+136.168.221.19 - - [15/Oct/1997:19:17:16 -0700] "GET /about.html HTTP/1.0" 200 6902+152.163.207.138 - - [15/Oct/1997:19:17:16 -0700] "GET /asa/china/images/punchy.gif HTTP/1.0" 304 -+136.168.221.19 - - [15/Oct/1997:19:17:17 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+136.168.221.19 - - [15/Oct/1997:19:17:17 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+136.168.221.19 - - [15/Oct/1997:19:17:18 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+152.163.207.138 - - [15/Oct/1997:19:17:19 -0700] "GET /asa/china/images/world.gif HTTP/1.0" 304 -+136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+136.168.221.19 - - [15/Oct/1997:19:17:21 -0700] "GET /images/where.gif HTTP/1.0" 200 605+136.168.221.19 - - [15/Oct/1997:19:17:22 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+136.168.221.19 - - [15/Oct/1997:19:17:22 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+136.168.221.19 - - [15/Oct/1997:19:17:23 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+136.168.221.19 - - [15/Oct/1997:19:17:25 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+136.168.221.19 - - [15/Oct/1997:19:18:51 -0700] "GET /about/history.html HTTP/1.0" 200 10342+136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250+136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+136.168.221.19 - - [15/Oct/1997:19:18:52 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+136.168.221.19 - - [15/Oct/1997:19:18:53 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820+136.168.221.19 - - [15/Oct/1997:19:18:53 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367+136.168.221.19 - - [15/Oct/1997:19:18:54 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+136.168.221.19 - - [15/Oct/1997:19:18:55 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400+136.168.221.19 - - [15/Oct/1997:19:18:56 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+136.168.221.19 - - [15/Oct/1997:19:18:56 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+136.168.221.19 - - [15/Oct/1997:19:18:57 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596+152.171.10.6 - - [15/Oct/1997:19:19:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+152.171.10.6 - - [15/Oct/1997:19:19:18 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+152.171.10.6 - - [15/Oct/1997:19:19:22 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+152.171.10.6 - - [15/Oct/1997:19:20:49 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+152.171.10.6 - - [15/Oct/1997:19:20:53 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+152.171.10.6 - - [15/Oct/1997:19:20:58 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+152.171.10.6 - - [15/Oct/1997:19:21:00 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+152.171.10.6 - - [15/Oct/1997:19:21:07 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+199.217.72.166 - - [15/Oct/1997:19:27:19 -0700] "GET /country/balkans HTTP/1.0" 301 196+199.217.72.166 - - [15/Oct/1997:19:27:21 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+199.217.72.166 - - [15/Oct/1997:19:27:23 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+199.217.72.166 - - [15/Oct/1997:19:27:24 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+199.217.72.166 - - [15/Oct/1997:19:27:26 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+199.217.72.166 - - [15/Oct/1997:19:27:26 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+199.217.72.166 - - [15/Oct/1997:19:27:30 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+199.217.72.166 - - [15/Oct/1997:19:27:30 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+199.217.72.166 - - [15/Oct/1997:19:27:42 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+199.217.72.166 - - [15/Oct/1997:19:27:42 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+203.18.134.1 - - [15/Oct/1997:19:27:44 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+203.18.134.1 - - [15/Oct/1997:19:27:46 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+203.18.134.1 - - [15/Oct/1997:19:27:47 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+203.18.134.1 - - [15/Oct/1997:19:27:48 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+203.18.134.1 - - [15/Oct/1997:19:27:49 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+203.18.134.1 - - [15/Oct/1997:19:27:50 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+203.18.134.1 - - [15/Oct/1997:19:27:51 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+203.18.134.1 - - [15/Oct/1997:19:27:52 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+203.18.134.1 - - [15/Oct/1997:19:27:53 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+203.18.134.1 - - [15/Oct/1997:19:27:54 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+203.18.134.1 - - [15/Oct/1997:19:27:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+203.18.134.1 - - [15/Oct/1997:19:27:56 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+203.18.134.1 - - [15/Oct/1997:19:27:58 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+203.18.134.1 - - [15/Oct/1997:19:27:58 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+203.18.134.1 - - [15/Oct/1997:19:27:59 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+203.18.134.1 - - [15/Oct/1997:19:28:02 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+203.18.134.1 - - [15/Oct/1997:19:28:03 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+203.18.134.1 - - [15/Oct/1997:19:28:04 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+203.18.134.1 - - [15/Oct/1997:19:28:06 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+203.18.134.1 - - [15/Oct/1997:19:28:08 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+203.18.134.1 - - [15/Oct/1997:19:28:09 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+203.18.134.1 - - [15/Oct/1997:19:28:09 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+203.18.134.1 - - [15/Oct/1997:19:28:10 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+203.18.134.1 - - [15/Oct/1997:19:28:11 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+203.18.134.1 - - [15/Oct/1997:19:28:12 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+203.18.134.1 - - [15/Oct/1997:19:28:13 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+204.192.112.114 - - [15/Oct/1997:19:28:28 -0700] "GET /robots.txt HTTP/1.0" 404 163+204.192.112.114 - - [15/Oct/1997:19:28:29 -0700] "GET / HTTP/1.0" 200 3082+203.18.134.1 - - [15/Oct/1997:19:28:51 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629+203.18.134.1 - - [15/Oct/1997:19:28:54 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638+203.18.134.1 - - [15/Oct/1997:19:28:55 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785+203.18.134.1 - - [15/Oct/1997:19:28:57 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859+203.18.134.1 - - [15/Oct/1997:19:28:58 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237+203.18.134.1 - - [15/Oct/1997:19:28:59 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903+203.18.134.1 - - [15/Oct/1997:19:29:01 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833+203.18.134.1 - - [15/Oct/1997:19:29:01 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352+203.18.134.1 - - [15/Oct/1997:19:29:03 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836+203.18.134.1 - - [15/Oct/1997:19:29:06 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429+203.18.134.1 - - [15/Oct/1997:19:29:06 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625+203.18.134.1 - - [15/Oct/1997:19:29:14 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509+203.18.134.1 - - [15/Oct/1997:19:29:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+203.18.134.1 - - [15/Oct/1997:19:32:09 -0700] "GET /amnesty/guatem/ndsa.html HTTP/1.0" 200 2605+203.18.134.1 - - [15/Oct/1997:19:32:11 -0700] "GET /amnesty/guatem/magglas2.jpg HTTP/1.0" 200 798+203.18.134.1 - - [15/Oct/1997:19:32:11 -0700] "GET /amnesty/images/wordo35c.jpg HTTP/1.0" 200 4123+203.18.134.1 - - [15/Oct/1997:19:32:13 -0700] "GET /amnesty/images/wordoll2.jpg HTTP/1.0" 200 3063+203.18.134.1 - - [15/Oct/1997:19:33:30 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+203.18.134.1 - - [15/Oct/1997:19:33:30 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+203.18.134.1 - - [15/Oct/1997:19:33:32 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+203.18.134.1 - - [15/Oct/1997:19:33:34 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+203.18.134.1 - - [15/Oct/1997:19:33:34 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+203.18.134.1 - - [15/Oct/1997:19:33:35 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+203.18.134.1 - - [15/Oct/1997:19:33:36 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+203.18.134.1 - - [15/Oct/1997:19:33:37 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+203.18.134.1 - - [15/Oct/1997:19:33:39 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+203.18.134.1 - - [15/Oct/1997:19:33:40 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+203.18.134.1 - - [15/Oct/1997:19:33:41 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+203.18.134.1 - - [15/Oct/1997:19:33:42 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731+203.18.134.1 - - [15/Oct/1997:19:33:43 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+203.18.134.1 - - [15/Oct/1997:19:33:47 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882+203.18.134.1 - - [15/Oct/1997:19:33:48 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924+203.18.134.1 - - [15/Oct/1997:19:33:48 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914+203.18.134.1 - - [15/Oct/1997:19:33:49 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951+203.18.134.1 - - [15/Oct/1997:19:33:50 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190+203.18.134.1 - - [15/Oct/1997:19:33:51 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155+203.18.134.1 - - [15/Oct/1997:19:33:51 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938+203.18.134.1 - - [15/Oct/1997:19:33:52 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865+203.18.134.1 - - [15/Oct/1997:19:33:52 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946+203.18.134.1 - - [15/Oct/1997:19:33:53 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191+203.18.134.1 - - [15/Oct/1997:19:33:54 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170+203.18.134.1 - - [15/Oct/1997:19:33:55 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311+203.18.134.1 - - [15/Oct/1997:19:33:56 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786+203.18.134.1 - - [15/Oct/1997:19:33:57 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+203.18.134.1 - - [15/Oct/1997:19:33:58 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+203.18.134.1 - - [15/Oct/1997:19:33:58 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+203.18.134.1 - - [15/Oct/1997:19:33:59 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+203.18.134.1 - - [15/Oct/1997:19:34:00 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157+203.18.134.1 - - [15/Oct/1997:19:34:01 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+203.18.134.1 - - [15/Oct/1997:19:34:01 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+203.18.134.1 - - [15/Oct/1997:19:34:02 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591+203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+203.18.134.1 - - [15/Oct/1997:19:34:03 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 28581+203.18.134.1 - - [15/Oct/1997:19:34:04 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+203.18.134.1 - - [15/Oct/1997:19:34:07 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+203.18.134.1 - - [15/Oct/1997:19:34:11 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+203.18.134.1 - - [15/Oct/1997:19:34:14 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+203.18.134.1 - - [15/Oct/1997:19:34:14 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+203.18.134.1 - - [15/Oct/1997:19:34:15 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+203.18.134.1 - - [15/Oct/1997:19:34:15 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+203.18.134.1 - - [15/Oct/1997:19:34:17 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+204.62.245.166 - - [15/Oct/1997:19:35:24 -0700] "GET /amnesty/guatem/uscondec.html HTTP/1.0" 200 3282+140.142.174.15 - - [15/Oct/1997:19:37:47 -0700] "GET /amnesty HTTP/1.0" 301 184+140.142.174.15 - - [15/Oct/1997:19:37:48 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+140.142.174.15 - - [15/Oct/1997:19:37:50 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+140.142.174.15 - - [15/Oct/1997:19:37:52 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+140.142.174.15 - - [15/Oct/1997:19:38:19 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+140.142.174.15 - - [15/Oct/1997:19:38:21 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+140.142.174.15 - - [15/Oct/1997:19:38:21 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+140.142.174.15 - - [15/Oct/1997:19:38:22 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+140.142.174.15 - - [15/Oct/1997:19:38:23 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+140.142.174.15 - - [15/Oct/1997:19:38:25 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+140.142.174.15 - - [15/Oct/1997:19:38:26 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+140.142.174.15 - - [15/Oct/1997:19:38:28 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+140.142.174.15 - - [15/Oct/1997:19:38:28 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+140.142.174.15 - - [15/Oct/1997:19:38:29 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+140.142.174.15 - - [15/Oct/1997:19:38:30 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+140.142.174.15 - - [15/Oct/1997:19:38:30 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889+140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482+140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849+140.142.174.15 - - [15/Oct/1997:19:38:32 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447+140.142.174.15 - - [15/Oct/1997:19:38:34 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+140.142.174.15 - - [15/Oct/1997:19:38:34 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+207.137.47.247 - - [15/Oct/1997:19:38:35 -0700] "GET /amnesty/guatem/howdolls.html HTTP/1.0" 200 4203+207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow1.jpg HTTP/1.0" 200 2635+207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow2.jpg HTTP/1.0" 200 4865+207.137.47.247 - - [15/Oct/1997:19:38:38 -0700] "GET /amnesty/images/dollhow3.jpg HTTP/1.0" 200 7300+207.137.47.247 - - [15/Oct/1997:19:38:41 -0700] "GET /amnesty/images/wordoll2.jpg HTTP/1.0" 200 3063+140.142.174.15 - - [15/Oct/1997:19:38:54 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+140.142.174.15 - - [15/Oct/1997:19:38:55 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+140.142.174.15 - - [15/Oct/1997:19:38:55 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+140.142.174.15 - - [15/Oct/1997:19:38:57 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+140.142.174.15 - - [15/Oct/1997:19:38:59 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+207.137.47.247 - - [15/Oct/1997:19:39:03 -0700] "GET /amnesty/images/dollhow4.jpg HTTP/1.0" 200 10830+140.142.174.15 - - [15/Oct/1997:19:39:08 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+140.142.174.15 - - [15/Oct/1997:19:40:26 -0700] "GET /amnesty/country.html HTTP/1.0" 200 1765+140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/tools/topline3.gif HTTP/1.0" 200 233+140.142.174.15 - - [15/Oct/1997:19:40:27 -0700] "GET /amnesty/tools/topline4.gif HTTP/1.0" 200 263+140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+140.142.174.15 - - [15/Oct/1997:19:40:28 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+140.142.174.15 - - [15/Oct/1997:19:40:41 -0700] "GET /amnesty/country/index.html HTTP/1.0" 200 2808+140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/balkhead.jpg HTTP/1.0" 200 5046+140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/rwanhea2.gif HTTP/1.0" 200 2737+140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/country/images/topline4.gif HTTP/1.0" 200 263+140.142.174.15 - - [15/Oct/1997:19:40:43 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+140.142.174.15 - - [15/Oct/1997:19:40:45 -0700] "GET /amnesty/country/images/nigeria3.gif HTTP/1.0" 200 1549+140.142.174.15 - - [15/Oct/1997:19:40:46 -0700] "GET /amnesty/country/images/topline3.gif HTTP/1.0" 200 233+140.142.174.15 - - [15/Oct/1997:19:40:55 -0700] "GET /amnesty/country/images/goddess3.jpg HTTP/1.0" 200 5491+140.142.174.15 - - [15/Oct/1997:19:40:56 -0700] "GET /amnesty/country/images/hrme2.jpg HTTP/1.0" 200 7337+140.142.174.15 - - [15/Oct/1997:19:40:56 -0700] "GET /amnesty/country/images/mandala2.jpg HTTP/1.0" 200 7568+32.96.68.164 - - [15/Oct/1997:19:41:08 -0700] "GET / HTTP/1.0" 200 3082+32.96.68.164 - - [15/Oct/1997:19:41:10 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+32.96.68.164 - - [15/Oct/1997:19:41:12 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+32.96.68.164 - - [15/Oct/1997:19:41:29 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+32.96.68.164 - - [15/Oct/1997:19:41:29 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+32.96.68.164 - - [15/Oct/1997:19:41:30 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+32.96.68.164 - - [15/Oct/1997:19:41:30 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+32.96.68.164 - - [15/Oct/1997:19:41:31 -0700] "GET /ainews.html HTTP/1.0" 200 13435+32.96.68.164 - - [15/Oct/1997:19:41:32 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+32.96.68.164 - - [15/Oct/1997:19:41:35 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+32.96.68.164 - - [15/Oct/1997:19:41:36 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+32.96.68.164 - - [15/Oct/1997:19:41:39 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+32.96.68.164 - - [15/Oct/1997:19:41:41 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+32.96.68.164 - - [15/Oct/1997:19:41:41 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+32.96.68.164 - - [15/Oct/1997:19:41:42 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+32.96.68.164 - - [15/Oct/1997:19:41:42 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+32.96.68.164 - - [15/Oct/1997:19:41:48 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+140.142.174.15 - - [15/Oct/1997:19:49:25 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+204.62.245.32 - - [15/Oct/1997:19:52:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+158.152.1.181 - - [15/Oct/1997:19:53:14 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+158.152.1.181 - - [15/Oct/1997:19:53:23 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+128.226.4.62 - - [15/Oct/1997:19:53:29 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+207.115.1.33 - - [15/Oct/1997:19:53:34 -0700] "GET / HTTP/1.0" 200 3082+128.226.4.62 - - [15/Oct/1997:19:53:35 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+128.226.4.62 - - [15/Oct/1997:19:53:35 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+207.115.1.33 - - [15/Oct/1997:19:53:36 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+207.115.1.33 - - [15/Oct/1997:19:53:37 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+128.226.4.62 - - [15/Oct/1997:19:53:47 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731+128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865+128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190+128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924+128.226.4.62 - - [15/Oct/1997:19:53:49 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914+128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311+128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155+128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170+128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938+128.226.4.62 - - [15/Oct/1997:19:53:50 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951+128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157+128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591+128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946+128.226.4.62 - - [15/Oct/1997:19:53:51 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882+128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 28581+128.226.4.62 - - [15/Oct/1997:19:53:52 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786+128.226.4.62 - - [15/Oct/1997:19:53:57 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191+128.226.4.62 - - [15/Oct/1997:19:54:12 -0700] "GET /amnesty/postcard/welact.html HTTP/1.0" 200 4640+128.226.4.62 - - [15/Oct/1997:19:54:17 -0700] "GET /amnesty/postcard/images/joinbut.gif HTTP/1.0" 200 409+128.226.4.62 - - [15/Oct/1997:19:54:17 -0700] "GET /amnesty/postcard/images/welbut.gif HTTP/1.0" 200 600+128.226.4.62 - - [15/Oct/1997:19:54:18 -0700] "GET /amnesty/postcard/images/aiusabut.gif HTTP/1.0" 200 591+128.226.4.62 - - [15/Oct/1997:19:54:18 -0700] "GET /amnesty/postcard/images/letbut.gif HTTP/1.0" 200 517+128.226.4.62 - - [15/Oct/1997:19:54:19 -0700] "GET /amnesty/postcard/images/w.gif HTTP/1.0" 200 565+128.226.4.62 - - [15/Oct/1997:19:54:20 -0700] "GET /amnesty/postcard/images/wombarb9.gif HTTP/1.0" 200 20647+207.115.1.33 - - [15/Oct/1997:19:54:34 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562+207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+207.115.1.33 - - [15/Oct/1997:19:54:38 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+207.115.1.33 - - [15/Oct/1997:19:54:41 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+207.115.1.33 - - [15/Oct/1997:19:54:42 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+128.226.4.62 - - [15/Oct/1997:19:54:45 -0700] "GET /amnesty/postcard/anyapp.html HTTP/1.0" 200 3797+128.226.4.62 - - [15/Oct/1997:19:54:46 -0700] "GET /amnesty/postcard/images/blkcnd2.gif HTTP/1.0" 200 1082+128.226.4.62 - - [15/Oct/1997:19:55:10 -0700] "GET /amnesty/postcard/anylett.html HTTP/1.0" 200 1489+207.115.1.33 - - [15/Oct/1997:19:56:16 -0700] "GET /asa/china/louisa-links.html HTTP/1.0" 200 1076+208.136.13.104 - - [15/Oct/1997:19:56:37 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+208.136.13.104 - - [15/Oct/1997:19:56:43 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+208.136.13.104 - - [15/Oct/1997:19:56:43 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+208.136.13.104 - - [15/Oct/1997:19:56:44 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+208.136.13.104 - - [15/Oct/1997:19:56:44 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+198.168.101.58 - - [15/Oct/1997:19:59:35 -0700] "GET / HTTP/1.0" 200 3082+198.168.101.58 - - [15/Oct/1997:19:59:37 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+198.168.101.58 - - [15/Oct/1997:19:59:39 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+128.226.4.62 - - [15/Oct/1997:20:00:03 -0700] "GET /amnesty/postcard/welgroup.html HTTP/1.0" 200 8002+128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/goldfla2.gif HTTP/1.0" 200 1161+128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/grncndl.gif HTTP/1.0" 200 1471+128.226.4.62 - - [15/Oct/1997:20:00:04 -0700] "GET /amnesty/postcard/images/weletbut.gif HTTP/1.0" 200 566+128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257+128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430+128.226.4.62 - - [15/Oct/1997:20:00:05 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013+198.110.98.5 - - [15/Oct/1997:20:01:07 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+128.226.4.62 - - [15/Oct/1997:20:01:13 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+128.226.4.62 - - [15/Oct/1997:20:01:20 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+128.226.4.62 - - [15/Oct/1997:20:01:21 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+128.226.4.62 - - [15/Oct/1997:20:01:22 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+128.226.4.62 - - [15/Oct/1997:20:01:23 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+128.226.4.62 - - [15/Oct/1997:20:01:37 -0700] "GET /amnesty/ainews/china/execrec.html HTTP/1.0" 200 6897+204.74.108.98 - - [15/Oct/1997:20:01:39 -0700] "GET / HTTP/1.0" 200 3082+204.74.108.98 - - [15/Oct/1997:20:01:40 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+204.74.108.98 - - [15/Oct/1997:20:01:40 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+204.74.108.98 - - [15/Oct/1997:20:02:01 -0700] "GET /home.html HTTP/1.0" 200 17233+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+204.74.108.98 - - [15/Oct/1997:20:02:02 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+204.74.108.98 - - [15/Oct/1997:20:02:03 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+204.74.108.98 - - [15/Oct/1997:20:02:04 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+204.74.108.98 - - [15/Oct/1997:20:02:05 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+128.226.4.62 - - [15/Oct/1997:20:02:06 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+204.74.108.98 - - [15/Oct/1997:20:02:07 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+204.74.108.98 - - [15/Oct/1997:20:02:08 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+204.201.210.19 - - [15/Oct/1997:20:02:35 -0700] "GET /country/balkans HTTP/1.0" 301 196+204.201.210.19 - - [15/Oct/1997:20:02:36 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+204.201.210.19 - - [15/Oct/1997:20:02:39 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+204.201.210.19 - - [15/Oct/1997:20:02:41 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+204.201.210.19 - - [15/Oct/1997:20:02:43 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+204.74.108.98 - - [15/Oct/1997:20:04:05 -0700] "GET /candatop.html HTTP/1.0" 200 10629+204.74.108.98 - - [15/Oct/1997:20:04:06 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638+204.74.108.98 - - [15/Oct/1997:20:04:06 -0700] "GET /images/done.gif HTTP/1.0" 200 4785+204.74.108.98 - - [15/Oct/1997:20:04:07 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833+204.74.108.98 - - [15/Oct/1997:20:04:07 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625+204.74.108.98 - - [15/Oct/1997:20:04:08 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+204.74.108.98 - - [15/Oct/1997:20:04:09 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+204.74.108.98 - - [15/Oct/1997:20:04:09 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+204.74.108.98 - - [15/Oct/1997:20:05:17 -0700] "GET /talun.html HTTP/1.0" 200 1210+204.74.108.98 - - [15/Oct/1997:20:05:31 -0700] "GET /reyes.html HTTP/1.0" 200 2137+204.74.108.98 - - [15/Oct/1997:20:05:32 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+204.74.108.98 - - [15/Oct/1997:20:05:46 -0700] "GET /turkoglu.html HTTP/1.0" 200 1176+204.201.210.19 - - [15/Oct/1997:20:05:47 -0700] "GET /country/index.html HTTP/1.0" 200 2808+204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/balkhead.jpg HTTP/1.0" 200 5046+204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/rwanhea2.gif HTTP/1.0" 200 2737+204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /country/images/topline4.gif HTTP/1.0" 200 263+204.201.210.19 - - [15/Oct/1997:20:05:49 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+204.201.210.19 - - [15/Oct/1997:20:05:52 -0700] "GET /country/images/nigeria3.gif HTTP/1.0" 200 1549+204.201.210.19 - - [15/Oct/1997:20:05:57 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 200 7568+204.201.210.19 - - [15/Oct/1997:20:05:57 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+204.201.210.19 - - [15/Oct/1997:20:05:59 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+204.201.210.19 - - [15/Oct/1997:20:05:59 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+204.201.210.19 - - [15/Oct/1997:20:06:01 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491+204.74.108.98 - - [15/Oct/1997:20:06:02 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+204.74.108.98 - - [15/Oct/1997:20:06:02 -0700] "GET /joinai.html HTTP/1.0" 200 4054+204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491+204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 200 7337+204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:06:30 -0700] "GET /country/images/topline3.gif HTTP/1.0" 200 233+204.201.210.19 - - [15/Oct/1997:20:06:34 -0700] "GET /country/rwanda/index.html HTTP/1.0" 200 1987+204.201.210.19 - - [15/Oct/1997:20:06:36 -0700] "GET /country/rwanda/images/rwanbg.jpg HTTP/1.0" 200 4042+204.201.210.19 - - [15/Oct/1997:20:06:36 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+204.201.210.19 - - [15/Oct/1997:20:06:45 -0700] "GET /country/rwanda/images/rwanhead.gif HTTP/1.0" 200 20639+209.12.153.58 - - [15/Oct/1997:20:07:06 -0700] "GET /amnesty/women/index.html HTTP/1.0" 200 8198+209.12.153.58 - - [15/Oct/1997:20:07:07 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+204.74.108.98 - - [15/Oct/1997:20:07:08 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+209.12.153.58 - - [15/Oct/1997:20:07:24 -0700] "GET /amnesty/women/images/unocal3.gif HTTP/1.0" 200 1170+209.12.153.58 - - [15/Oct/1997:20:07:30 -0700] "GET /amnesty/women/images/enronlog.gif HTTP/1.0" 200 17130+209.12.153.58 - - [15/Oct/1997:20:07:45 -0700] "GET /amnesty/women/images/sari1.gif HTTP/1.0" 200 1784+209.12.153.58 - - [15/Oct/1997:20:07:46 -0700] "GET /amnesty/women/images/afgref2.jpg HTTP/1.0" 200 3853+209.12.153.58 - - [15/Oct/1997:20:07:46 -0700] "GET /amnesty/women/images/afwom5.jpg HTTP/1.0" 200 3853+209.12.153.58 - - [15/Oct/1997:20:07:48 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575+204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:07:57 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+204.201.210.19 - - [15/Oct/1997:20:07:58 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 206 4709+204.201.210.19 - - [15/Oct/1997:20:07:58 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 6555+204.201.210.19 - - [15/Oct/1997:20:07:59 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 5250+204.201.210.19 - - [15/Oct/1997:20:08:00 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+209.12.153.58 - - [15/Oct/1997:20:08:01 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+209.12.153.58 - - [15/Oct/1997:20:08:03 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+209.12.153.58 - - [15/Oct/1997:20:08:04 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+209.12.153.58 - - [15/Oct/1997:20:08:06 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+209.12.153.58 - - [15/Oct/1997:20:08:07 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161+209.12.153.58 - - [15/Oct/1997:20:08:07 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471+209.12.153.58 - - [15/Oct/1997:20:08:09 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+209.12.153.58 - - [15/Oct/1997:20:08:15 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+209.12.153.58 - - [15/Oct/1997:20:08:21 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013+209.12.153.58 - - [15/Oct/1997:20:08:36 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430+204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:08:42 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 206 3954+204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 5800+204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 4496+204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /images/newbutx.gif HTTP/1.0" 206 930+204.201.210.19 - - [15/Oct/1997:20:08:43 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /images/amnty1.gif HTTP/1.0" 200 3013+204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /images/nigeria2.gif HTTP/1.0" 200 2518+204.201.210.19 - - [15/Oct/1997:20:09:00 -0700] "GET /nigsham.html HTTP/1.0" 200 19559+204.201.210.19 - - [15/Oct/1997:20:09:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.201.210.19 - - [15/Oct/1997:20:09:08 -0700] "GET /images/chris.jpg HTTP/1.0" 200 8302+204.201.210.19 - - [15/Oct/1997:20:09:08 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+209.12.153.58 - - [15/Oct/1997:20:09:10 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399+204.201.210.19 - - [15/Oct/1997:20:09:11 -0700] "GET /images/image1.jpg HTTP/1.0" 200 8557+209.12.153.58 - - [15/Oct/1997:20:09:12 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257+204.201.210.19 - - [15/Oct/1997:20:09:13 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+204.201.210.19 - - [15/Oct/1997:20:09:13 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+204.201.210.19 - - [15/Oct/1997:20:09:15 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+204.201.210.19 - - [15/Oct/1997:20:09:38 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+204.201.210.19 - - [15/Oct/1997:20:09:39 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 206 1462+204.201.210.19 - - [15/Oct/1997:20:09:39 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 206 1694+204.201.210.19 - - [15/Oct/1997:20:09:40 -0700] "GET /images/aboutbux.gif HTTP/1.0" 206 850+209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/afgref2.jpg HTTP/1.0" 304 -+209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/afwom5.jpg HTTP/1.0" 304 -+209.12.153.58 - - [15/Oct/1997:20:09:53 -0700] "GET /amnesty/women/images/sari1.gif HTTP/1.0" 200 1784+146.6.94.50 - - [15/Oct/1997:20:10:07 -0700] "GET / HTTP/1.0" 200 3082+146.6.94.50 - - [15/Oct/1997:20:10:17 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+146.6.94.50 - - [15/Oct/1997:20:10:21 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+38.14.126.160 - - [15/Oct/1997:20:11:51 -0700] "GET / HTTP/1.0" 200 3082+38.14.126.160 - - [15/Oct/1997:20:11:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+38.14.126.160 - - [15/Oct/1997:20:11:53 -0700] "GET /images/spot5.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:08 -0700] "GET /country HTTP/1.0" 301 188+38.14.126.160 - - [15/Oct/1997:20:12:08 -0700] "GET /country/ HTTP/1.0" 200 2808+38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/balkhead.jpg HTTP/1.0" 200 5046+38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/rwanhea2.gif HTTP/1.0" 200 2737+38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /country/images/topline4.gif HTTP/1.0" 200 263+38.14.126.160 - - [15/Oct/1997:20:12:11 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:12 -0700] "GET /country/images/mandala2.jpg HTTP/1.0" 200 7568+38.14.126.160 - - [15/Oct/1997:20:12:12 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:15 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /country/images/goddess3.jpg HTTP/1.0" 200 5491+38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /country/images/hrme2.jpg HTTP/1.0" 200 7337+38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:20 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:23 -0700] "GET /country/images/nigeria3.gif HTTP/1.0" 200 1549+38.14.126.160 - - [15/Oct/1997:20:12:23 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:28 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+38.14.126.160 - - [15/Oct/1997:20:12:31 -0700] "GET /country/images/topline3.gif HTTP/1.0" 200 233+206.86.247.122 - - [15/Oct/1997:20:16:38 -0700] "GET /usalinks.html HTTP/1.0" 200 10329+206.86.247.122 - - [15/Oct/1997:20:16:44 -0700] "GET /amnesty/fw.html HTTP/1.0" 200 779+203.116.1.245 - - [15/Oct/1997:20:16:52 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+192.65.17.24 - - [15/Oct/1997:20:20:26 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+192.65.17.24 - - [15/Oct/1997:20:20:31 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+192.65.17.24 - - [15/Oct/1997:20:20:33 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+192.65.17.24 - - [15/Oct/1997:20:20:56 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+192.65.17.24 - - [15/Oct/1997:20:21:08 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+192.65.17.24 - - [15/Oct/1997:20:23:40 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+192.65.17.24 - - [15/Oct/1997:20:23:49 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+192.65.17.24 - - [15/Oct/1997:20:23:49 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+192.65.17.24 - - [15/Oct/1997:20:23:50 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+192.65.17.24 - - [15/Oct/1997:20:23:54 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+192.65.17.24 - - [15/Oct/1997:20:23:56 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+192.65.17.24 - - [15/Oct/1997:20:23:56 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889+192.65.17.24 - - [15/Oct/1997:20:23:57 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482+192.65.17.24 - - [15/Oct/1997:20:23:57 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447+192.65.17.24 - - [15/Oct/1997:20:23:59 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849+192.65.17.24 - - [15/Oct/1997:20:24:02 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+192.65.17.24 - - [15/Oct/1997:20:24:03 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+38.14.126.160 - - [15/Oct/1997:20:24:07 -0700] "GET /country/balkans HTTP/1.0" 301 196+38.14.126.160 - - [15/Oct/1997:20:24:08 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+38.14.126.160 - - [15/Oct/1997:20:24:11 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+38.14.126.160 - - [15/Oct/1997:20:24:12 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+38.14.126.160 - - [15/Oct/1997:20:24:12 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+38.14.126.160 - - [15/Oct/1997:20:24:13 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+38.14.126.160 - - [15/Oct/1997:20:24:14 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+38.14.126.160 - - [15/Oct/1997:20:24:16 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+192.65.17.24 - - [15/Oct/1997:20:24:33 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+192.65.17.24 - - [15/Oct/1997:20:24:36 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+192.65.17.24 - - [15/Oct/1997:20:24:37 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+192.65.17.24 - - [15/Oct/1997:20:24:37 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+192.65.17.24 - - [15/Oct/1997:20:24:46 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+192.65.17.24 - - [15/Oct/1997:20:24:46 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+192.65.17.24 - - [15/Oct/1997:20:24:47 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+192.65.17.24 - - [15/Oct/1997:20:24:52 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+192.65.17.24 - - [15/Oct/1997:20:24:53 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+192.65.17.24 - - [15/Oct/1997:20:24:56 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+192.65.17.24 - - [15/Oct/1997:20:24:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+192.65.17.24 - - [15/Oct/1997:20:24:57 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+192.65.17.24 - - [15/Oct/1997:20:24:58 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+192.65.17.24 - - [15/Oct/1997:20:24:58 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+192.65.17.24 - - [15/Oct/1997:20:24:59 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+192.65.17.24 - - [15/Oct/1997:20:24:59 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+192.65.17.24 - - [15/Oct/1997:20:25:00 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+192.65.17.24 - - [15/Oct/1997:20:25:09 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+192.65.17.24 - - [15/Oct/1997:20:25:14 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+192.65.17.24 - - [15/Oct/1997:20:25:37 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283+192.65.17.24 - - [15/Oct/1997:20:25:41 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+192.65.17.24 - - [15/Oct/1997:20:25:42 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+192.65.17.24 - - [15/Oct/1997:20:25:45 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+192.65.17.24 - - [15/Oct/1997:20:25:45 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+192.65.17.24 - - [15/Oct/1997:20:25:47 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+192.65.17.24 - - [15/Oct/1997:20:27:22 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074+192.65.17.24 - - [15/Oct/1997:20:27:23 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43+132.254.40.136 - - [15/Oct/1997:20:30:29 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+132.254.40.136 - - [15/Oct/1997:20:30:32 -0700] "GET /amnesty/latinam/spoeadp.html HTTP/1.0" 200 8540+128.8.21.79 - - [15/Oct/1997:20:34:34 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+128.8.21.79 - - [15/Oct/1997:20:34:37 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+128.8.21.79 - - [15/Oct/1997:20:34:42 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+128.8.21.79 - - [15/Oct/1997:20:34:46 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+128.8.21.79 - - [15/Oct/1997:20:35:04 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+128.8.21.79 - - [15/Oct/1997:20:35:04 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+128.8.21.79 - - [15/Oct/1997:20:35:05 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+128.8.21.79 - - [15/Oct/1997:20:35:05 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+128.8.21.79 - - [15/Oct/1997:20:35:10 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+128.8.21.79 - - [15/Oct/1997:20:35:10 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+128.8.21.79 - - [15/Oct/1997:20:35:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+128.8.21.79 - - [15/Oct/1997:20:35:17 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+128.8.21.79 - - [15/Oct/1997:20:35:20 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+128.8.21.79 - - [15/Oct/1997:20:35:24 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+128.8.21.79 - - [15/Oct/1997:20:35:27 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+128.8.21.79 - - [15/Oct/1997:20:35:27 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+128.8.21.79 - - [15/Oct/1997:20:35:28 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+128.8.21.79 - - [15/Oct/1997:20:35:29 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+128.8.21.79 - - [15/Oct/1997:20:35:30 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+128.8.21.79 - - [15/Oct/1997:20:35:48 -0700] "GET /amnesty/country.html HTTP/1.0" 200 1765+128.8.21.79 - - [15/Oct/1997:20:35:50 -0700] "GET /amnesty/tools/topline4.gif HTTP/1.0" 200 263+128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+128.8.21.79 - - [15/Oct/1997:20:35:51 -0700] "GET /amnesty/tools/topline3.gif HTTP/1.0" 200 233+128.8.21.79 - - [15/Oct/1997:20:35:52 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+128.8.21.79 - - [15/Oct/1997:20:35:53 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+128.8.21.79 - - [15/Oct/1997:20:35:54 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+128.8.21.79 - - [15/Oct/1997:20:35:55 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+204.162.96.93 - - [15/Oct/1997:20:35:57 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292+128.8.21.79 - - [15/Oct/1997:20:36:07 -0700] "GET /amnesty/country/index.html HTTP/1.0" 200 2808+128.8.21.79 - - [15/Oct/1997:20:36:09 -0700] "GET /amnesty/country/images/topline4.gif HTTP/1.0" 200 263+128.8.21.79 - - [15/Oct/1997:20:36:09 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+128.8.21.79 - - [15/Oct/1997:20:36:10 -0700] "GET /amnesty/country/images/balkhead.jpg HTTP/1.0" 200 5046+128.8.21.79 - - [15/Oct/1997:20:36:10 -0700] "GET /amnesty/country/images/rwanhea2.gif HTTP/1.0" 200 2737+128.8.21.79 - - [15/Oct/1997:20:36:13 -0700] "GET /amnesty/country/images/goddess3.jpg HTTP/1.0" 200 5491+128.8.21.79 - - [15/Oct/1997:20:36:14 -0700] "GET /amnesty/country/images/nigeria3.gif HTTP/1.0" 200 1549+128.8.21.79 - - [15/Oct/1997:20:36:18 -0700] "GET /amnesty/country/images/hrme2.jpg HTTP/1.0" 200 7337+128.8.21.79 - - [15/Oct/1997:20:36:22 -0700] "GET /amnesty/country/images/mandala2.jpg HTTP/1.0" 200 7568+128.8.21.79 - - [15/Oct/1997:20:36:25 -0700] "GET /amnesty/country/images/topline3.gif HTTP/1.0" 200 233+128.8.21.79 - - [15/Oct/1997:20:36:54 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629+128.8.21.79 - - [15/Oct/1997:20:36:55 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785+128.8.21.79 - - [15/Oct/1997:20:36:56 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237+128.8.21.79 - - [15/Oct/1997:20:37:03 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638+128.8.21.79 - - [15/Oct/1997:20:37:04 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352+128.8.21.79 - - [15/Oct/1997:20:37:06 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859+polux.entelchile.net - - [15/Oct/1997:21:02:07 -0700] "GET /latinam/spoeadp.html HTTP/1.0" 200 8540+polux.entelchile.net - - [15/Oct/1997:21:02:29 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+ws186.library.msstate.edu - - [15/Oct/1997:21:02:44 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292+ws186.library.msstate.edu - - [15/Oct/1997:21:02:45 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:02:49 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:09 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:09 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:10 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:15 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:17 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:03:17 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:04:58 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:10 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:16 -0700] "GET /amnesty/urgact HTTP/1.0" 301 191+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:05:18 -0700] "GET /amnesty/urgact/ HTTP/1.0" 200 8283+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:33 -0700] "GET /amnesty/urgact/uafaq.html HTTP/1.0" 200 20157+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:55 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:56 -0700] "GET /amnesty/urgac HTTP/1.0" 404 166+1cust230.tnt3.krk1.da.uu.net - - [15/Oct/1997:21:06:58 -0700] "GET /amnesty/urgact/urgact.html HTTP/1.0" 404 179+ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:07 -0700] "GET /amnesty HTTP/1.0" 301 184+ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:09 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:12 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:17 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ip051029.dialup.wvnet.edu - - [15/Oct/1997:21:07:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+polux.entelchile.net - - [15/Oct/1997:21:08:38 -0700] "GET /ainews.html HTTP/1.0" 200 13435+polux.entelchile.net - - [15/Oct/1997:21:08:44 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+polux.entelchile.net - - [15/Oct/1997:21:09:01 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+polux.entelchile.net - - [15/Oct/1997:21:09:10 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+polux.entelchile.net - - [15/Oct/1997:21:09:10 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+polux.entelchile.net - - [15/Oct/1997:21:09:23 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:33 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:35 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:36 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+ww-tq03.proxy.aol.com - - [15/Oct/1997:21:11:37 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:13:59 -0700] "GET / HTTP/1.0" 200 3082+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:01 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:03 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:23 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:25 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:28 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:31 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:31 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:32 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:34 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:34 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:35 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:36 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:37 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:38 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:39 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:41 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:47 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:49 -0700] "GET /group.html HTTP/1.0" 200 8575+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:50 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:53 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:14:57 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:15:00 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:15:09 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:14 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:18 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:22 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:33 -0700] "GET /urgact/index.html HTTP/1.0" 200 8283+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:36 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:37 -0700] "GET /index.html HTTP/1.0" 200 3082+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:40 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:42 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:17:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+anx-lkf0044.deltanet.com - - [15/Oct/1997:21:17:58 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:31 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:34 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:35 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:18:35 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:34 -0700] "GET /about.html HTTP/1.0" 200 6902+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:36 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:37 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/where.gif HTTP/1.0" 200 605+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:38 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:39 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:39 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:19:40 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:11 -0700] "GET /group.html HTTP/1.0" 200 8575+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:19 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:20 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399+proxy4.ykt.prodigy.net - - [15/Oct/1997:21:22:21 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430+ppp23.fortworth.dfw.net - - [15/Oct/1997:22:04:57 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+al-jacob.wvmccd.cc.ca.us - - [15/Oct/1997:22:05:24 -0700] "GET / HTTP/1.0" 200 3082+proxy4.la.prodigy.net - - [15/Oct/1997:22:05:26 -0700] "GET /casework/index.html HTTP/1.0" 304 -+proxy4.la.prodigy.net - - [15/Oct/1997:22:05:27 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+proxy4.la.prodigy.net - - [15/Oct/1997:22:05:29 -0700] "GET /casework/index.html HTTP/1.0" 304 -+proxy4.la.prodigy.net - - [15/Oct/1997:22:05:30 -0700] "GET /casework/index.html HTTP/1.0" 304 -+proxy4.la.prodigy.net - - [15/Oct/1997:22:05:32 -0700] "GET /casework/index.html HTTP/1.0" 304 -+wdcsun2.usdoj.gov - - [15/Oct/1997:22:05:58 -0700] "GET /amnesty/women/afghaii.html HTTP/1.0" 200 3854+ip051029.dialup.wvnet.edu - - [15/Oct/1997:22:10:45 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178+globulus.itd.uts.edu.au - - [15/Oct/1997:22:14:51 -0700] "GET /women/enronbac.html HTTP/1.0" 200 6806+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:02 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:05 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:05 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:11 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:12 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+globulus.itd.uts.edu.au - - [15/Oct/1997:22:15:25 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:01 -0700] "GET / HTTP/1.0" 200 3082+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:15 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:16 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:42 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+ldn99-1.leiden.nl.net - - [15/Oct/1997:22:21:45 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:49 -0700] "GET /joinai.html HTTP/1.0" 200 4054+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:51 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:53 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:53 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:54 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:21:54 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:22:02 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:25:05 -0700] "GET /joinai.txt HTTP/1.0" 200 1914+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:28:46 -0700] "GET /home.html HTTP/1.0" 200 3854+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:28:59 -0700] "GET /home.html HTTP/1.0" 200 17233+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:03 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:03 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:05 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:06 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:07 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:12 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:13 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:13 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:14 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:18 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:18 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:19 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+ww-tr05.proxy.aol.com - - [15/Oct/1997:22:29:19 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+templeton-bbn.infoseek.com - - [15/Oct/1997:22:53:53 -0700] "GET /robots.txt HTTP/1.0" 404 163+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:53:56 -0700] "GET / HTTP/1.0" 200 3082+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+slip166-72-240-91.oh.us.ibm.net - - [15/Oct/1997:22:54:15 -0700] "GET / HTTP/1.0" 200 3082+slip166-72-240-91.oh.us.ibm.net - - [15/Oct/1997:22:54:17 -0700] "GET /amnesty/usalinks.html HTTP/1.0" 200 3854+templeton-bbn.infoseek.com - - [15/Oct/1997:22:54:17 -0700] "GET /asa/china/ HTTP/1.0" 200 3854+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:19 -0700] "GET /welcome.html HTTP/1.0" 200 4731+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:21 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:22 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:22 -0700] "GET /images/never.gif HTTP/1.0" 200 914+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:25 -0700] "GET /images/a.gif HTTP/1.0" 200 865+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:26 -0700] "GET /images/commit.gif HTTP/1.0" 200 190+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:26 -0700] "GET /images/rights.gif HTTP/1.0" 200 938+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:28 -0700] "GET /images/canred.gif HTTP/1.0" 200 311+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:30 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:32 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:33 -0700] "GET /images/human.gif HTTP/1.0" 200 155+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:33 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:34 -0700] "GET /images/differ.gif HTTP/1.0" 200 191+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:36 -0700] "GET /images/your.gif HTTP/1.0" 200 951+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:37 -0700] "GET /images/can.gif HTTP/1.0" 200 946+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:37 -0700] "GET /images/it.gif HTTP/1.0" 200 170+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:40 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157+ppp-206-170-32-226.snfc21.pacbell.net - - [15/Oct/1997:22:54:43 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581+ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+ww-tk61.proxy.aol.com - - [15/Oct/1997:22:57:54 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+piweba5y-ext.prodigy.com - - [15/Oct/1997:23:00:34 -0700] "GET / HTTP/1.0" 200 3082+146.7.214.63 - - [15/Oct/1997:23:04:37 -0700] "GET /comm/stewart.html HTTP/1.0" 200 1648+146.7.214.63 - - [15/Oct/1997:23:04:46 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517+146.7.214.63 - - [15/Oct/1997:23:04:52 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43+146.7.214.63 - - [15/Oct/1997:23:04:54 -0700] "GET /comm/images/people/stew4.jpg HTTP/1.0" 200 11278+templeton-bbn.infoseek.com - - [15/Oct/1997:23:31:38 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:45:48 -0700] "GET /whatsnew.html** HTTP/1.0" 404 168+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:10 -0700] "GET /whatsnew.html** HTTP/1.0" 404 168+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:32 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/homenew.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:36 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+ip160.ridgewood.nj.pub-ip.psi.net - - [15/Oct/1997:23:46:37 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+j8.inktomi.com - - [15/Oct/1997:23:47:57 -0700] "GET /education HTTP/1.0" 301 190+pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:02 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+pool027-max6.gardena-ca-us.dialup.earthlink.net - - [16/Oct/1997:00:05:09 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+galore-bbn.infoseek.com - - [16/Oct/1997:00:35:46 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:36 -0700] "GET /urgact/ HTTP/1.0" 200 8283+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:38 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+adialup151.phnx.uswest.net - - [16/Oct/1997:00:56:42 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+203.21.39.23 - - [16/Oct/1997:00:57:21 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:49 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:51 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:51 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+ww-tn05.proxy.aol.com - - [16/Oct/1997:01:03:53 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+widow.av.pa-x.dec.com - - [16/Oct/1997:01:18:00 -0700] "GET /amnesty/so-cal.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:01:19:14 -0700] "GET /amnesty/index.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:01:21:40 -0700] "GET /amnesty/guatem/iobdecl.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:01:25:45 -0700] "GET /amnesty/guatem/ndsa4.html HTTP/1.0" 304 -+md18-228.mun.compuserve.com - - [16/Oct/1997:01:33:20 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+templeton-bbn.infoseek.com - - [16/Oct/1997:01:35:20 -0700] "GET /amnesty/regions/maregcon.html HTTP/1.0" 304 -+templeton-bbn.infoseek.com - - [16/Oct/1997:01:37:42 -0700] "GET /robots.txt HTTP/1.0" 404 163+templeton-bbn.infoseek.com - - [16/Oct/1997:01:37:52 -0700] "GET /education/ HTTP/1.0" 200 -+lsc070067.res-hall.nwu.edu - - [16/Oct/1997:01:40:55 -0700] "GET /amnesty/regions/startrek.html HTTP/1.0" 404 182+px1.syd.aone.net.au - - [16/Oct/1997:01:45:47 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+px1.syd.aone.net.au - - [16/Oct/1997:01:45:48 -0700] "GET /feats/coptrain.html HTTP/1.0" 200 20726+widow.av.pa-x.dec.com - - [16/Oct/1997:01:48:43 -0700] "GET /amnesty/guatem/ngodcl.html HTTP/1.0" 304 -+stargate.uni-paderborn.de - - [16/Oct/1997:01:50:47 -0700] "GET / HTTP/1.0" 200 3082+stargate.uni-paderborn.de - - [16/Oct/1997:01:50:51 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+stargate.uni-paderborn.de - - [16/Oct/1997:01:50:52 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:04 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:04 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:05 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:06 -0700] "GET /home.html HTTP/1.0" 200 17233+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:06 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:07 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:08 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:10 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:11 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:14 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:15 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:15 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:16 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:18 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:23 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:26 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:27 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:29 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:30 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:32 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:33 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+widow.av.pa-x.dec.com - - [16/Oct/1997:01:51:48 -0700] "GET /amnesty/guatem/huelgade.html HTTP/1.0" 304 -+stargate.uni-paderborn.de - - [16/Oct/1997:01:51:53 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+aluminum.elemental.ultra.net.au - - [16/Oct/1997:02:00:52 -0700] "GET /images/suu50b.jpg HTTP/1.0" 200 17237+aluminum.elemental.ultra.net.au - - [16/Oct/1997:02:00:52 -0700] "GET /myanmar/aungsan.html HTTP/1.0" 200 14464+widow.av.pa-x.dec.com - - [16/Oct/1997:02:02:43 -0700] "GET /amnesty/guatem/guatcamp.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:02:04:50 -0700] "GET /amnesty/guatem/guatdc.html HTTP/1.0" 304 -+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:51 -0700] "GET /amnesty HTTP/1.0" 301 184+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:52 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:54 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:06:57 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:12 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+barracuda.res.wpi.net - - [16/Oct/1997:02:07:13 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+barracuda.res.wpi.net - - [16/Oct/1997:02:07:14 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:16 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:17 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:18 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:18 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:21 -0700] "GET /asa/china/ HTTP/1.1" 200 18000+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:21 -0700] "GET /asa/china/contents.html HTTP/1.1" 200 3336+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:29 -0700] "GET /asa/china/chinese.html HTTP/1.1" 200 15983+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:32 -0700] "GET /asa/china/images/welcome.gif HTTP/1.1" 200 1049+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:37 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.1" 200 27794+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:42 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:42 -0700] "GET /asa/china/images/hk.gif HTTP/1.1" 200 1212+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:45 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:07:46 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:46 -0700] "GET /asa/china/images/tibet.gif HTTP/1.1" 200 1241+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:47 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.1" 200 36122+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:50 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.1" 200 4196+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:50 -0700] "GET /asa/china/images/xj.gif HTTP/1.1" 200 1247+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:53 -0700] "GET /asa/china/images/link.gif HTTP/1.1" 200 4236+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:55 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.1" 200 2899+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:55 -0700] "GET /asa/china/images/renquan.gif HTTP/1.1" 200 411+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:56 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.1" 200 3648+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:56 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.1" 200 1202+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:07:59 -0700] "GET /asa/china/images/aichico.gif HTTP/1.1" 200 4724+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:03 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.1" 200 17344+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:04 -0700] "GET /asa/china/images/animai.gif HTTP/1.1" 200 5175+1cust40.max6.santa-clara.ca.ms.uu.net - - [16/Oct/1997:02:08:05 -0700] "GET /asa/china/images/smflag.gif HTTP/1.1" 200 951+ti18a37-0013.dialup.online.no - - [16/Oct/1997:02:08:44 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:41 -0700] "GET / HTTP/1.0" 200 3082+ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:43 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+ww-to06.proxy.aol.com - - [16/Oct/1997:02:10:44 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+widow.av.pa-x.dec.com - - [16/Oct/1997:02:14:00 -0700] "GET /amnesty/guatem/uscondec.html HTTP/1.0" 304 -+lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:41 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534+lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/amnty1.gif HTTP/1.0" 200 3013+lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/back.gif HTTP/1.0" 200 224+lp02port26.highway.telekom.at - - [16/Oct/1997:02:14:44 -0700] "GET /amnesty/turkey/clear.gif HTTP/1.0" 200 76+gk-red.unicc.org - - [16/Oct/1997:02:15:54 -0700] "GET / HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:17:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:17:12 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:17:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:17:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:17:16 -0700] "GET / HTTP/1.0" 200 3082+dialup74-3-48.swipnet.se - - [16/Oct/1997:02:17:58 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:02:18:01 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+dialup74-3-48.swipnet.se - - [16/Oct/1997:02:18:01 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+dialup74-3-48.swipnet.se - - [16/Oct/1997:02:18:03 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+dialup74-3-48.swipnet.se - - [16/Oct/1997:02:19:48 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+dialup74-3-48.swipnet.se - - [16/Oct/1997:02:24:38 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+obatanga.chat.carleton.ca - - [16/Oct/1997:02:26:06 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178+142.los-angeles-09.ca.dial-access.att.net - - [16/Oct/1997:02:37:00 -0700] "GET /home.html HTTP/1.0" 200 17233+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:22 -0700] "GET /i-what.html HTTP/1.0" 404 164+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:42 -0700] "GET / HTTP/1.0" 200 3082+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:45 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:46 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:42:57 -0700] "GET /about.html HTTP/1.0" 200 6902+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:00 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:01 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:03 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:04 -0700] "GET /images/where.gif HTTP/1.0" 200 605+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:43 -0700] "GET /about/history.html HTTP/1.0" 200 10342+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:44 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:45 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:45 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:46 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:47 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:47 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:48 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:43:48 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:45:13 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+gymnasiet-4.hanko.fi - - [16/Oct/1997:02:45:23 -0700] "GET /i-what.html HTTP/1.0" 404 164+194.158.162.143 - - [16/Oct/1997:02:50:22 -0700] "GET /country/balkans HTTP/1.0" 301 196+194.158.162.143 - - [16/Oct/1997:02:50:23 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+194.158.162.143 - - [16/Oct/1997:02:50:27 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+194.158.162.143 - - [16/Oct/1997:02:50:27 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188+194.158.162.143 - - [16/Oct/1997:02:50:29 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+194.158.162.143 - - [16/Oct/1997:02:50:33 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+194.158.162.143 - - [16/Oct/1997:02:50:33 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188+194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+194.158.162.143 - - [16/Oct/1997:02:50:36 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+194.158.162.143 - - [16/Oct/1997:02:50:37 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188+194.158.162.143 - - [16/Oct/1997:02:50:37 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+195.53.57.2 - - [16/Oct/1997:02:53:15 -0700] "GET /latinam/spoeadp.html HTTP/1.0" 200 8540+195.53.57.2 - - [16/Oct/1997:02:53:20 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+widow.av.pa-x.dec.com - - [16/Oct/1997:02:53:28 -0700] "GET /amnesty/guatem/guatdocs.html HTTP/1.0" 304 -+194.158.162.143 - - [16/Oct/1997:02:54:10 -0700] "GET /country/balkans HTTP/1.0" 301 196+194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /home.html HTTP/1.0" 200 17233+194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+194.158.162.143 - - [16/Oct/1997:02:54:56 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+194.158.162.143 - - [16/Oct/1997:02:54:57 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+194.158.162.143 - - [16/Oct/1997:02:54:58 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+194.158.162.143 - - [16/Oct/1997:02:55:00 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+194.158.162.143 - - [16/Oct/1997:02:55:01 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+194.158.162.143 - - [16/Oct/1997:02:55:01 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+194.158.162.143 - - [16/Oct/1997:02:55:02 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+194.158.162.143 - - [16/Oct/1997:02:55:04 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+194.158.162.143 - - [16/Oct/1997:02:55:05 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+194.158.162.143 - - [16/Oct/1997:02:55:09 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+194.158.162.143 - - [16/Oct/1997:02:55:10 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+194.158.162.143 - - [16/Oct/1997:02:55:14 -0700] "GET /ainews.html HTTP/1.0" 200 13435+194.158.162.143 - - [16/Oct/1997:02:55:15 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+194.158.162.143 - - [16/Oct/1997:02:55:15 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+194.158.162.143 - - [16/Oct/1997:02:55:16 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+194.158.162.143 - - [16/Oct/1997:02:55:17 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+194.158.162.143 - - [16/Oct/1997:02:55:17 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+194.158.162.143 - - [16/Oct/1997:02:55:18 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+194.158.162.143 - - [16/Oct/1997:02:55:20 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+194.158.162.143 - - [16/Oct/1997:02:56:03 -0700] "GET /ainews/cuba/criticsp.html HTTP/1.0" 200 7711+194.158.162.143 - - [16/Oct/1997:02:56:04 -0700] "GET /ainews/images/blkcnd2.gif HTTP/1.0" 200 1082+194.158.162.143 - - [16/Oct/1997:02:56:12 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+widow.av.pa-x.dec.com - - [16/Oct/1997:03:02:49 -0700] "GET /amnesty/guatem/aidecl.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:03:18:20 -0700] "GET /amnesty/guatem/guatacts.html HTTP/1.0" 304 -+widow.av.pa-x.dec.com - - [16/Oct/1997:03:27:46 -0700] "GET /amnesty/guatem/bgdecl.html HTTP/1.0" 304 -+ppp066.b.ite.net - - [16/Oct/1997:03:36:06 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ppp066.b.ite.net - - [16/Oct/1997:03:36:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ppp066.b.ite.net - - [16/Oct/1997:03:36:12 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ppp066.b.ite.net - - [16/Oct/1997:03:37:04 -0700] "GET /amnesty/about.html HTTP/1.0" 200 6902+ppp066.b.ite.net - - [16/Oct/1997:03:37:06 -0700] "GET /amnesty/images/howbut.gif HTTP/1.0" 200 509+ppp066.b.ite.net - - [16/Oct/1997:03:37:07 -0700] "GET /amnesty/images/whobut.gif HTTP/1.0" 200 505+ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/whatbut.gif HTTP/1.0" 200 526+ppp066.b.ite.net - - [16/Oct/1997:03:37:11 -0700] "GET /amnesty/images/where.gif HTTP/1.0" 200 605+ppp066.b.ite.net - - [16/Oct/1997:03:37:17 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/aalogo.gif HTTP/1.0" 200 15293+ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+ppp066.b.ite.net - - [16/Oct/1997:03:37:18 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+ppp066.b.ite.net - - [16/Oct/1997:03:37:22 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+ppp066.b.ite.net - - [16/Oct/1997:03:38:33 -0700] "GET /amnesty/images/done.gif HTTP/1.0" 200 4785+ppp066.b.ite.net - - [16/Oct/1997:03:38:34 -0700] "GET /amnesty/candatop.html HTTP/1.0" 200 10629+ppp066.b.ite.net - - [16/Oct/1997:03:38:48 -0700] "GET /amnesty/images/candalog.gif HTTP/1.0" 200 8638+ppp066.b.ite.net - - [16/Oct/1997:03:38:50 -0700] "GET /amnesty/images/reyes.gif HTTP/1.0" 200 10859+ppp066.b.ite.net - - [16/Oct/1997:03:38:56 -0700] "GET /amnesty/images/kids5.jpg HTTP/1.0" 200 2903+ppp066.b.ite.net - - [16/Oct/1997:03:38:56 -0700] "GET /amnesty/images/reddash2.gif HTTP/1.0" 200 237+ppp066.b.ite.net - - [16/Oct/1997:03:38:58 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836+ppp066.b.ite.net - - [16/Oct/1997:03:39:03 -0700] "GET /amnesty/images/hasene2.gif HTTP/1.0" 200 8833+ppp066.b.ite.net - - [16/Oct/1997:03:39:08 -0700] "GET /amnesty/images/nigpost1.gif HTTP/1.0" 200 4429+ppp066.b.ite.net - - [16/Oct/1997:03:39:08 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+ppp066.b.ite.net - - [16/Oct/1997:03:39:09 -0700] "GET /amnesty/images/turkboy.gif HTTP/1.0" 200 4625+ppp066.b.ite.net - - [16/Oct/1997:03:39:14 -0700] "GET /amnesty/images/rally4.jpg HTTP/1.0" 200 7352+ppp066.b.ite.net - - [16/Oct/1997:03:39:20 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+ppp066.b.ite.net - - [16/Oct/1997:03:39:23 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+ppp066.b.ite.net - - [16/Oct/1997:03:40:09 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:42:31 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:42:34 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+widow.av.pa-x.dec.com - - [16/Oct/1997:03:42:40 -0700] "GET /amnesty/guatem/guatstud.html HTTP/1.0" 304 -+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:06 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:10 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:10 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:11 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:14 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:15 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:18 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:19 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:21 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+proxyf11.cyberway.com.sg - - [16/Oct/1997:03:43:22 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+141.244.102.33 - - [16/Oct/1997:03:57:32 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+141.244.102.33 - - [16/Oct/1997:03:59:17 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855+141.244.102.33 - - [16/Oct/1997:03:59:30 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855+141.244.102.33 - - [16/Oct/1997:03:59:43 -0700] "GET /amnesty/ainews/congo_rwanda/massinc.html HTTP/1.0" 200 3855+202.231.192.180 - - [16/Oct/1997:04:09:02 -0700] "GET /usalinks.html HTTP/1.0" 200 10329+202.231.192.180 - - [16/Oct/1997:04:09:05 -0700] "GET /images/ai_cand1.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:05 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:09 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:12 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+202.231.192.180 - - [16/Oct/1997:04:09:12 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43+hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+hud02a01.ml.com - - [16/Oct/1997:04:20:42 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074+hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+hud02a01.ml.com - - [16/Oct/1997:04:20:43 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+hud02a01.ml.com - - [16/Oct/1997:04:20:44 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+hud02a01.ml.com - - [16/Oct/1997:04:23:03 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:03 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812+hud02a01.ml.com - - [16/Oct/1997:04:23:04 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:05 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:23:06 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 -+203.8.223.2 - - [16/Oct/1997:04:23:54 -0700] "GET /amnesty/feats/china1.html HTTP/1.0" 200 3303+203.8.223.2 - - [16/Oct/1997:04:24:10 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+hud02a01.ml.com - - [16/Oct/1997:04:25:20 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+hud02a01.ml.com - - [16/Oct/1997:04:25:21 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+hud02a01.ml.com - - [16/Oct/1997:04:25:22 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+hud02a01.ml.com - - [16/Oct/1997:04:25:23 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:31 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+m.johns.slip.auckland.ac.nz - - [16/Oct/1997:04:28:34 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/images/linebrn.gif HTTP/1.0" 200 308+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:26 -0700] "GET /amnesty/weeklyua.html HTTP/1.0" 200 10887+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:30 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:32 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:29:32 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+proxyf11.cyberway.com.sg - - [16/Oct/1997:04:30:45 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+hud02a01.ml.com - - [16/Oct/1997:04:32:30 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:30 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+hud02a01.ml.com - - [16/Oct/1997:04:32:32 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074+hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+hud02a01.ml.com - - [16/Oct/1997:04:32:33 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+hud02a01.ml.com - - [16/Oct/1997:04:32:34 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:38 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812+hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:04:32:39 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 -+202.54.52.100 - - [16/Oct/1997:04:39:23 -0700] "GET /amnesty/immigr.html HTTP/1.0" 200 11284+poppy.mcc.ac.uk - - [16/Oct/1997:04:39:29 -0700] "GET /asa/china/ HTTP/1.0" 200 18000+poppy.mcc.ac.uk - - [16/Oct/1997:04:41:03 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336+poppy.mcc.ac.uk - - [16/Oct/1997:04:42:08 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951+poppy.mcc.ac.uk - - [16/Oct/1997:04:42:18 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 200 5175+poppy.mcc.ac.uk - - [16/Oct/1997:04:42:21 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983+widow.av.pa-x.dec.com - - [16/Oct/1997:04:42:49 -0700] "GET /amnesty/guatem/howdolls.html HTTP/1.0" 304 -+poppy.mcc.ac.uk - - [16/Oct/1997:04:43:15 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+poppy.mcc.ac.uk - - [16/Oct/1997:04:43:15 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196+poppy.mcc.ac.uk - - [16/Oct/1997:04:44:14 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241+poppy.mcc.ac.uk - - [16/Oct/1997:04:44:28 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247+poppy.mcc.ac.uk - - [16/Oct/1997:04:45:10 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724+poppy.mcc.ac.uk - - [16/Oct/1997:04:46:10 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049+poppy.mcc.ac.uk - - [16/Oct/1997:04:46:48 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899+palo10.pacific.net.sg - - [16/Oct/1997:04:48:08 -0700] "GET / HTTP/1.0" 200 3082+poppy.mcc.ac.uk - - [16/Oct/1997:04:49:04 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236+poppy.mcc.ac.uk - - [16/Oct/1997:04:49:15 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 16384+poppy.mcc.ac.uk - - [16/Oct/1997:04:49:29 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 206 2114+palo10.pacific.net.sg - - [16/Oct/1997:04:49:46 -0700] "GET /ainews.html HTTP/1.0" 200 13435+poppy.mcc.ac.uk - - [16/Oct/1997:04:50:04 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 206 19844+poppy.mcc.ac.uk - - [16/Oct/1997:04:50:58 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411+poppy.mcc.ac.uk - - [16/Oct/1997:04:51:03 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344+palo10.pacific.net.sg - - [16/Oct/1997:04:51:10 -0700] "GET /ainews/singapore/sue.html HTTP/1.0" 200 5225+poppy.mcc.ac.uk - - [16/Oct/1997:04:51:45 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202+poppy.mcc.ac.uk - - [16/Oct/1997:04:51:54 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 9487+poppy.mcc.ac.uk - - [16/Oct/1997:04:52:47 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 304 -+poppy.mcc.ac.uk - - [16/Oct/1997:04:52:58 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 206 30731+palo10.pacific.net.sg - - [16/Oct/1997:04:53:23 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+poppy.mcc.ac.uk - - [16/Oct/1997:04:54:46 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 206 11441+ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:07 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+ip244.baltimore3.md.pub-ip.psi.net - - [16/Oct/1997:05:00:10 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:38 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:38 -0700] "GET /amnesty/images/refrun1.gif HTTP/1.0" 200 836+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:39 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:39 -0700] "GET /amnesty/images/turqbut.gif HTTP/1.0" 200 903+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:42 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:48 -0700] "GET /amnesty/refugee/refqa.html HTTP/1.0" 200 18657+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+ccds232.ccds.cincinnati.oh.us - - [16/Oct/1997:05:05:49 -0700] "GET /amnesty/images/morinfox.gif HTTP/1.0" 200 2056+pc5249.cmiu.bt.co.uk - - [16/Oct/1997:05:14:20 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534+194.184.94.45 - - [16/Oct/1997:05:15:30 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+204.232.49.4 - - [16/Oct/1997:05:15:32 -0700] "GET / HTTP/1.0" 200 3082+204.232.49.4 - - [16/Oct/1997:05:15:39 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+204.232.49.4 - - [16/Oct/1997:05:15:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+206.23.223.136 - - [16/Oct/1997:05:16:05 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178+rolf.powersim.no - - [16/Oct/1997:05:16:28 -0700] "GET /spanish/images/yi.gif HTTP/1.0" 200 16599+193.213.14.50 - - [16/Oct/1997:05:16:29 -0700] "GET /spanish/fwspupda.html HTTP/1.0" 200 4283+rolf.powersim.no - - [16/Oct/1997:05:16:30 -0700] "GET /spanish/images/padilla2.gif HTTP/1.0" 200 12312+rolf.powersim.no - - [16/Oct/1997:05:16:31 -0700] "GET /spanish/images/ghaleh.gif HTTP/1.0" 200 27250+pc26.huron.ac.uk - - [16/Oct/1997:05:17:43 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+204.232.49.4 - - [16/Oct/1997:05:21:44 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+204.232.49.4 - - [16/Oct/1997:05:21:44 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+204.232.49.4 - - [16/Oct/1997:05:21:45 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+204.232.49.4 - - [16/Oct/1997:05:21:46 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+204.232.49.4 - - [16/Oct/1997:05:21:53 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+204.232.49.4 - - [16/Oct/1997:05:21:54 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+204.232.49.4 - - [16/Oct/1997:05:21:55 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+204.232.49.4 - - [16/Oct/1997:05:21:57 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+204.232.49.4 - - [16/Oct/1997:05:21:57 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+204.232.49.4 - - [16/Oct/1997:05:21:58 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+204.232.49.4 - - [16/Oct/1997:05:21:59 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+204.232.49.4 - - [16/Oct/1997:05:22:03 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.232.49.4 - - [16/Oct/1997:05:22:03 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+204.232.49.4 - - [16/Oct/1997:05:22:07 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+204.232.49.4 - - [16/Oct/1997:05:22:07 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+204.232.49.4 - - [16/Oct/1997:05:22:11 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+204.232.49.4 - - [16/Oct/1997:05:22:12 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+204.232.49.4 - - [16/Oct/1997:05:22:15 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+204.232.49.4 - - [16/Oct/1997:05:22:16 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+204.232.49.4 - - [16/Oct/1997:05:22:17 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+204.232.49.4 - - [16/Oct/1997:05:22:19 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+204.232.49.4 - - [16/Oct/1997:05:22:21 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+ircf.funet.fi - - [16/Oct/1997:05:26:47 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+hhtam025027.netvigator.com - - [16/Oct/1997:05:29:57 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+207.38.218.70 - - [16/Oct/1997:05:30:56 -0700] "GET /ainews.html HTTP/1.0" 304 -+hhtam025027.netvigator.com - - [16/Oct/1997:05:30:56 -0700] "GET /asa/china/consdoc.html HTTP/1.0" 200 32768+207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:00 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /images/refhand4.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:01 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 3854+207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+207.38.218.70 - - [16/Oct/1997:05:31:02 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:09 -0700] "GET / HTTP/1.0" 200 3082+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:11 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:15 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:38 -0700] "GET /amnesty/asa/china/images/animai.gif HTTP/1.0" 200 5175+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:39 -0700] "GET /amnesty/asa/china/images/smflag.gif HTTP/1.0" 200 951+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:44 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:44 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:45 -0700] "GET /amnesty/asa/china/chinese.html HTTP/1.0" 200 15983+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/hk.gif HTTP/1.0" 200 1212+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/mail8380.gif HTTP/1.0" 200 4196+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/tibet.gif HTTP/1.0" 200 1241+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:47 -0700] "GET /amnesty/asa/china/images/xj.gif HTTP/1.0" 200 1247+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:48 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:31:48 -0700] "GET /amnesty/asa/china/images/aichico.gif HTTP/1.0" 200 4724+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:51 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:51 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:58 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:58 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:59 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+pppch146141.dacom.co.kr - - [16/Oct/1997:05:31:59 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:02 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:04 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:06 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:07 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+s09-pm02.milledgeville.campus.mci.net - - [16/Oct/1997:05:32:09 -0700] "GET /amnesty/asa/china/images/mailbox1.gif HTTP/1.0" 200 17344+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:09 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:10 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:11 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:15 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:15 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:21 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:27 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:30 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+pppch146141.dacom.co.kr - - [16/Oct/1997:05:32:38 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+207.38.218.70 - - [16/Oct/1997:05:32:39 -0700] "GET /ainews.html HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /images/newslogo.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:41 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+207.38.218.70 - - [16/Oct/1997:05:32:42 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:43 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+207.38.218.70 - - [16/Oct/1997:05:32:44 -0700] "GET /images/homebut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:44 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/countbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/joinbut.gif HTTP/1.0" 304 -+207.38.218.70 - - [16/Oct/1997:05:32:45 -0700] "GET /images/netbut.gif HTTP/1.0" 304 -+pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:23 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:23 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:27 -0700] "GET /ainews.html HTTP/1.0" 200 13435+pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:27 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+pppch146141.dacom.co.kr - - [16/Oct/1997:05:33:31 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 8192+198.215.121.135 - - [16/Oct/1997:05:37:18 -0700] "GET /asa/china/ HTTP/1.0" 200 18000+198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 15983+198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336+198.215.121.135 - - [16/Oct/1997:05:37:19 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/animai.gif HTTP/1.0" 200 5175+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241+198.215.121.135 - - [16/Oct/1997:05:37:20 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247+198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724+198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122+198.215.121.135 - - [16/Oct/1997:05:37:21 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247+198.215.121.135 - - [16/Oct/1997:05:37:22 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899+198.215.121.135 - - [16/Oct/1997:05:37:22 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236+198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196+198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344+198.215.121.135 - - [16/Oct/1997:05:37:23 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648+198.215.121.135 - - [16/Oct/1997:05:37:24 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202+198.215.121.135 - - [16/Oct/1997:05:37:26 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:46:47 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:46:48 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:02 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 3855+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:15 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:21 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:23 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:23 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:47:34 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 3854+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:27 -0700] "GET /amnesty/home.html HTTP/1.0" 200 3854+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:27 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 3854+pc21.ipc.univ-metz.fr - - [16/Oct/1997:05:48:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:48:31 -0700] "GET /amnesty/pakistan/viol.html HTTP/1.0" 200 7679+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:48:34 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+198.108.140.121 - - [16/Oct/1997:05:50:41 -0700] "GET /amnesty/usa/assault.html HTTP/1.0" 200 4292+198.108.140.121 - - [16/Oct/1997:05:50:42 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+mso94.marsweb.com - - [16/Oct/1997:05:51:27 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:48 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:48 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:49 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:52 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:52 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:51:55 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:00 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:19 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 3855+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:23 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:25 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:28 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:29 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:31 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:32 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:33 -0700] "GET /amnesty/images/netbut.gif HTTP/1.0" 200 1191+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:36 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:52:37 -0700] "GET /amnesty/urgact/contact.html HTTP/1.0" 200 882+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:38 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:41 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+207.38.218.89 - - [16/Oct/1997:05:52:42 -0700] "GET / HTTP/1.0" 200 -+207.38.218.89 - - [16/Oct/1997:05:52:44 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+207.38.218.89 - - [16/Oct/1997:05:52:44 -0700] "GET /images/spot5.gif HTTP/1.0" 304 -+hhtam005082.netvigator.com - - [16/Oct/1997:05:52:45 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 8192+hhtam005082.netvigator.com - - [16/Oct/1997:05:53:13 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 304 -+hhtam005082.netvigator.com - - [16/Oct/1997:05:53:14 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+hhtam005082.netvigator.com - - [16/Oct/1997:05:53:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+hhtam005082.netvigator.com - - [16/Oct/1997:05:53:15 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 304 -+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:17 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+hhtam005082.netvigator.com - - [16/Oct/1997:05:53:18 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 206 6029+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:20 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:21 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:21 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:22 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:23 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:24 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:25 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:25 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:26 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:26 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:27 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:27 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:28 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:31 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:47 -0700] "GET /amnesty/members.html HTTP/1.0" 200 1501+s4.usr1.ww-interlink.net - - [16/Oct/1997:05:53:49 -0700] "GET /amnesty/images/memlogo.gif HTTP/1.0" 200 7872+ehv51-2.eindhoven.nl.net - - [16/Oct/1997:06:00:03 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:10 -0700] "GET /country/balkans HTTP/1.0" 301 196+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:18 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:28 -0700] "GET /country/balkans/images/ailogo.gif HTTP/1.0" 200 3630+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:28 -0700] "GET /country/balkans/images/dot.gif%20ALT= HTTP/1.0" 404 188+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:29 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:30 -0700] "GET /country/balkans/images/albania.gif HTTP/1.0" 200 314+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:30 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:54 -0700] "GET /country/balkans/images/fry.gif HTTP/1.0" 200 984+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:54 -0700] "GET /country/balkans/images/mace.gif HTTP/1.0" 200 429+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:55 -0700] "GET /country/balkans/images/croatia.gif HTTP/1.0" 200 354+ww-ta05.proxy.aol.com - - [16/Oct/1997:06:00:55 -0700] "GET /country/balkans/images/slovenia.gif HTTP/1.0" 200 376+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:06 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:10 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:11 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:18 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:20 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:21 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:22 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:43 -0700] "GET /amnesty/ainews/usa/texas.html HTTP/1.0" 200 5825+ti34a96-0155.dialup.online.no - - [16/Oct/1997:06:01:45 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:19 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:22 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:22 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:24 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:24 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:26 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:27 -0700] "GET /asa/china/images/ic_pict.gif HTTP/1.0" 200 2899+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:32 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:33 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:34 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:38 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:43 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 27794+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:44 -0700] "GET /asa/china/images/aichico.gif HTTP/1.0" 200 4724+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:45 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 36122+spc-isp-ott-uas-2-65.sprint.ca - - [16/Oct/1997:06:06:52 -0700] "GET /asa/china/images/mailbox1.gif HTTP/1.0" 200 17344+208.195.7.217 - - [16/Oct/1997:06:08:32 -0700] "GET / HTTP/1.0" 200 3082+208.195.7.217 - - [16/Oct/1997:06:08:36 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+208.195.7.217 - - [16/Oct/1997:06:08:36 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+208.195.7.217 - - [16/Oct/1997:06:08:57 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+208.195.7.217 - - [16/Oct/1997:06:08:59 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+208.195.7.217 - - [16/Oct/1997:06:08:59 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+208.195.7.217 - - [16/Oct/1997:06:09:00 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+208.195.7.217 - - [16/Oct/1997:06:09:05 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+208.195.7.217 - - [16/Oct/1997:06:09:05 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+208.195.7.217 - - [16/Oct/1997:06:09:06 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+208.195.7.217 - - [16/Oct/1997:06:09:06 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+208.195.7.217 - - [16/Oct/1997:06:09:07 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+208.195.7.217 - - [16/Oct/1997:06:09:09 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+208.195.7.217 - - [16/Oct/1997:06:09:10 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+208.195.7.217 - - [16/Oct/1997:06:09:11 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+208.195.7.217 - - [16/Oct/1997:06:09:12 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+208.195.7.217 - - [16/Oct/1997:06:09:14 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+208.195.7.217 - - [16/Oct/1997:06:09:14 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+208.195.7.217 - - [16/Oct/1997:06:09:16 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+208.195.7.217 - - [16/Oct/1997:06:09:16 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+208.195.7.217 - - [16/Oct/1997:06:09:17 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+208.195.7.217 - - [16/Oct/1997:06:09:18 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+208.195.7.217 - - [16/Oct/1997:06:09:45 -0700] "GET /casework/index.html HTTP/1.0" 200 2974+208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/aiusarex.gif HTTP/1.0" 200 3237+208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+208.195.7.217 - - [16/Oct/1997:06:09:49 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+208.195.7.217 - - [16/Oct/1997:06:09:50 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 200 8650+208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+208.195.7.217 - - [16/Oct/1997:06:09:54 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+208.195.7.217 - - [16/Oct/1997:06:09:55 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+208.195.7.217 - - [16/Oct/1997:06:10:12 -0700] "GET /casework/fw.html HTTP/1.0" 200 5528+208.195.7.217 - - [16/Oct/1997:06:10:18 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 200 1158+208.195.7.217 - - [16/Oct/1997:06:10:18 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 200 10003+208.195.7.217 - - [16/Oct/1997:06:11:51 -0700] "GET /casework/fw1.html HTTP/1.0" 200 2813+199.250.191.4 - - [16/Oct/1997:06:14:38 -0700] "GET /urgact/ HTTP/1.0" 200 8283+ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:46 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:48 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:49 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+ww-pa01.proxy.aol.com - - [16/Oct/1997:06:17:49 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+spg-tnt12s127.erols.com - - [16/Oct/1997:06:21:24 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:28 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:30 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+spg-tnt12s127.erols.com - - [16/Oct/1997:06:22:38 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562+207.38.218.77 - - [16/Oct/1997:06:23:09 -0700] "GET /images/ai_cand1.gif HTTP/1.0" 200 6328+207.38.218.77 - - [16/Oct/1997:06:23:09 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+207.38.218.77 - - [16/Oct/1997:06:23:12 -0700] "GET /usalinks.html HTTP/1.0" 200 10329+207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+207.38.218.77 - - [16/Oct/1997:06:23:13 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+207.38.218.77 - - [16/Oct/1997:06:23:15 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+207.38.218.77 - - [16/Oct/1997:06:23:15 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+207.38.218.77 - - [16/Oct/1997:06:23:37 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+207.38.218.77 - - [16/Oct/1997:06:23:37 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+207.38.218.77 - - [16/Oct/1997:06:23:38 -0700] "GET /home.html HTTP/1.0" 200 17233+207.38.218.77 - - [16/Oct/1997:06:23:40 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+207.38.218.77 - - [16/Oct/1997:06:23:40 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+207.38.218.77 - - [16/Oct/1997:06:23:41 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+207.38.218.77 - - [16/Oct/1997:06:23:42 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+207.38.218.77 - - [16/Oct/1997:06:23:42 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+207.38.218.77 - - [16/Oct/1997:06:23:43 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+207.38.218.77 - - [16/Oct/1997:06:23:44 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+207.38.218.77 - - [16/Oct/1997:06:23:44 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /ainews.html HTTP/1.0" 200 13435+207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+207.38.218.77 - - [16/Oct/1997:06:23:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+207.38.218.77 - - [16/Oct/1997:06:23:48 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+207.38.218.77 - - [16/Oct/1997:06:23:48 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+207.38.218.77 - - [16/Oct/1997:06:23:49 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+207.38.218.77 - - [16/Oct/1997:06:23:50 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+207.38.218.77 - - [16/Oct/1997:06:23:51 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 8192+207.38.218.77 - - [16/Oct/1997:06:23:52 -0700] "GET /ainews/israel_occupied_territories/killing.html HTTP/1.0" 200 6647+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:07 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:09 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:14 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:17 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:18 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:24 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:25 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+spg-tnt12s127.erols.com - - [16/Oct/1997:06:24:33 -0700] "GET /amnesty/asa/china/louisa-links.html HTTP/1.0" 200 1076+hud02a01.ml.com - - [16/Oct/1997:06:26:23 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:24 -0700] "GET /amnesty/urgact/newslett.html HTTP/1.0" 200 26074+hud02a01.ml.com - - [16/Oct/1997:06:26:25 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:25 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:26 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+hud02a01.ml.com - - [16/Oct/1997:06:26:27 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+hud02a01.ml.com - - [16/Oct/1997:06:26:31 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:31 -0700] "GET /amnesty/urgact/nl0997.html HTTP/1.0" 200 18812+hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:32 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:33 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 304 -+hud02a01.ml.com - - [16/Oct/1997:06:26:36 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 304 -+spg-tnt12s127.erols.com - - [16/Oct/1997:06:27:11 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+spg-tnt12s127.erols.com - - [16/Oct/1997:06:27:48 -0700] "GET /amnesty/asa/china/chadrel-newsflash.html HTTP/1.0" 200 1084+spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:00 -0700] "GET /amnesty/asa/china/images/c_chinma.jpg HTTP/1.0" 200 4655+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:00 -0700] "GET /casework/index.html HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/aiusarex.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:02 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:04 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:05 -0700] "GET /amnesty/asa/china/images/newsflas.gif HTTP/1.0" 200 2340+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:14 -0700] "GET /casework/fw.html HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:16 -0700] "GET /casework/images/amnesty.gif HTTP/1.0" 304 -+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:28:16 -0700] "GET /casework/images/stamptil.jpg HTTP/1.0" 304 -+spg-tnt12s127.erols.com - - [16/Oct/1997:06:28:31 -0700] "GET /amnesty/asa/china/images/chadrel.jpg HTTP/1.0" 200 20391+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:29:11 -0700] "GET /casework/fw1.html HTTP/1.0" 304 -+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:35 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:43 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:44 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:47 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:48 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:51 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:54 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:55 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+spg-tnt12s127.erols.com - - [16/Oct/1997:06:29:58 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:09 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:33 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:35 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:46 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:53 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:54 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+spg-tnt12s127.erols.com - - [16/Oct/1997:06:30:55 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:09 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:37 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:41 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+proxy1.ykt.prodigy.net - - [16/Oct/1997:06:31:41 -0700] "GET /casework/fw2.html HTTP/1.0" 304 -+spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:49 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+spg-tnt12s127.erols.com - - [16/Oct/1997:06:31:55 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:02 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:06 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:08 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:09 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+spg-tnt12s127.erols.com - - [16/Oct/1997:06:32:14 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+194.151.13.64 - - [16/Oct/1997:06:33:36 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+spg-tnt12s127.erols.com - - [16/Oct/1997:06:33:37 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283+193.63.139.50 - - [16/Oct/1997:06:34:03 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+gk-red.unicc.org - - [16/Oct/1997:06:34:29 -0700] "GET /amnesty/mideast/libya.html HTTP/1.0" 200 6278+gk-red.unicc.org - - [16/Oct/1997:06:34:36 -0700] "GET /amnesty/mideast/libya.jpg HTTP/1.0" 200 4641+gk-red.unicc.org - - [16/Oct/1997:06:34:39 -0700] "GET /amnesty/mideast/libflag.gif HTTP/1.0" 200 1364+gk-red.unicc.org - - [16/Oct/1997:06:34:41 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202+spg-tnt12s127.erols.com - - [16/Oct/1997:06:35:46 -0700] "GET /amnesty/urgact/index.html HTTP/1.0" 200 8283+spg-tnt12s127.erols.com - - [16/Oct/1997:06:35:48 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+131.123.15.27 - - [16/Oct/1997:06:35:54 -0700] "GET /images/aiusa2.gif HTTP/1.0" 200 2905+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:36:26 -0700] "GET /amnesty/death/cabana.html HTTP/1.0" 404 178+krafla.rhi.hi.is - - [16/Oct/1997:06:36:29 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+krafla.rhi.hi.is - - [16/Oct/1997:06:36:30 -0700] "GET /amnesty/about/history.html HTTP/1.0" 200 10342+krafla.rhi.hi.is - - [16/Oct/1997:06:38:41 -0700] "GET /amnesty/about/images/masthd3.gif HTTP/1.0" 200 33250+130inf121.cinet.es - - [16/Oct/1997:06:38:47 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+130inf121.cinet.es - - [16/Oct/1997:06:39:15 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+130inf121.cinet.es - - [16/Oct/1997:06:39:37 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/hometake.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:37 -0700] "GET /images/writbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:38 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:38 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:39 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:39 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:40 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/homenew.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:44 -0700] "GET /images/homeside.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:45 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:47 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:47 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:48 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:48 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/countbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/savebutx.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:49 -0700] "GET /images/spanbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:50 -0700] "GET /images/getbut.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:39:50 -0700] "GET /images/membutx.gif HTTP/1.0" 304 -+130inf121.cinet.es - - [16/Oct/1997:06:40:13 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+dialup177-1-5.swipnet.se - - [16/Oct/1997:06:41:32 -0700] "GET /amnesty/casework/fwq&a.html HTTP/1.0" 200 6329+146.186.150.185 - - [16/Oct/1997:06:45:20 -0700] "GET / HTTP/1.0" 200 3082+146.186.150.185 - - [16/Oct/1997:06:45:21 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+146.186.150.185 - - [16/Oct/1997:06:45:21 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+146.186.150.185 - - [16/Oct/1997:06:45:45 -0700] "GET /about.html HTTP/1.0" 200 6902+146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+146.186.150.185 - - [16/Oct/1997:06:45:46 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+146.186.150.185 - - [16/Oct/1997:06:45:47 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+146.186.150.185 - - [16/Oct/1997:06:45:47 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+146.186.150.185 - - [16/Oct/1997:06:45:48 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+146.186.150.185 - - [16/Oct/1997:06:45:52 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+146.186.150.185 - - [16/Oct/1997:06:45:53 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+146.186.150.185 - - [16/Oct/1997:06:45:54 -0700] "GET /images/where.gif HTTP/1.0" 200 605+palo1.pacific.net.sg - - [16/Oct/1997:06:45:57 -0700] "GET /amnesty HTTP/1.0" 301 184+palo1.pacific.net.sg - - [16/Oct/1997:06:45:59 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+palo1.pacific.net.sg - - [16/Oct/1997:06:46:03 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /group.html HTTP/1.0" 200 8575+146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/goldfla2.gif HTTP/1.0" 200 1161+146.186.150.185 - - [16/Oct/1997:06:46:21 -0700] "GET /images/grncndl.gif HTTP/1.0" 200 1471+146.186.150.185 - - [16/Oct/1997:06:46:22 -0700] "GET /images/canfuz1.gif HTTP/1.0" 200 3013+146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/04candle.gif HTTP/1.0" 200 7257+146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+146.186.150.185 - - [16/Oct/1997:06:46:23 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+146.186.150.185 - - [16/Oct/1997:06:46:24 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+palo1.pacific.net.sg - - [16/Oct/1997:06:46:25 -0700] "GET /amnesty/ainews.html HTTP/1.0" 200 13435+146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/evenbut.gif HTTP/1.0" 200 399+146.186.150.185 - - [16/Oct/1997:06:46:25 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+146.186.150.185 - - [16/Oct/1997:06:46:28 -0700] "GET /images/can1_2.gif HTTP/1.0" 200 30430+palo1.pacific.net.sg - - [16/Oct/1997:06:46:32 -0700] "GET /amnesty/images/ai_emb2.gif HTTP/1.0" 200 2189+palo1.pacific.net.sg - - [16/Oct/1997:06:46:32 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+palo1.pacific.net.sg - - [16/Oct/1997:06:46:33 -0700] "GET /amnesty/images/newslogo.gif HTTP/1.0" 200 17448+palo1.pacific.net.sg - - [16/Oct/1997:06:46:40 -0700] "GET /amnesty/spanish/images/spespbut.gif HTTP/1.0" 200 427+palo1.pacific.net.sg - - [16/Oct/1997:06:46:42 -0700] "GET /amnesty/images/refhand4.gif HTTP/1.0" 200 6789+palo1.pacific.net.sg - - [16/Oct/1997:06:46:48 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+palo1.pacific.net.sg - - [16/Oct/1997:06:46:51 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+146.186.150.185 - - [16/Oct/1997:06:46:54 -0700] "GET /ann-rpt.html HTTP/1.0" 200 1899+146.186.150.185 - - [16/Oct/1997:06:46:55 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+146.186.150.185 - - [16/Oct/1997:06:46:55 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+146.186.150.185 - - [16/Oct/1997:06:47:02 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+146.186.150.185 - - [16/Oct/1997:06:47:06 -0700] "GET /ar-sum.html HTTP/1.0" 200 27608+ppp44.igc.org - - [16/Oct/1997:06:47:08 -0700] "GET /regions/west.html HTTP/1.0" 200 5900+palo1.pacific.net.sg - - [16/Oct/1997:06:47:10 -0700] "GET /amnesty/ainews/singapore/sue.html HTTP/1.0" 200 5225+ppp44.igc.org - - [16/Oct/1997:06:47:10 -0700] "GET /images/bg.gif HTTP/1.0" 200 2464+ppp44.igc.org - - [16/Oct/1997:06:47:11 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 -+ppp44.igc.org - - [16/Oct/1997:06:47:13 -0700] "GET /images/refuges1.jpg HTTP/1.0" 200 7377+ppp44.igc.org - - [16/Oct/1997:06:47:16 -0700] "GET /images/border15.jpg HTTP/1.0" 200 5092+gate2.bankerstrust.com - - [16/Oct/1997:06:47:38 -0700] "GET /comm/jagger.html HTTP/1.0" 200 1864+gate2.bankerstrust.com - - [16/Oct/1997:06:47:44 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43+gate2.bankerstrust.com - - [16/Oct/1997:06:47:46 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517+gate2.bankerstrust.com - - [16/Oct/1997:06:47:46 -0700] "GET /comm/images/people/jagger4.jpg HTTP/1.0" 200 10112+gate2.bankerstrust.com - - [16/Oct/1997:06:48:18 -0700] "GET /comm/medaward.html HTTP/1.0" 200 6483+docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:21 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:21 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+docrefoff5.library.emory.edu - - [16/Oct/1997:06:48:22 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+gate2.bankerstrust.com - - [16/Oct/1997:06:48:27 -0700] "GET /comm/images/starblu.jpg HTTP/1.0" 200 5498+gate2.bankerstrust.com - - [16/Oct/1997:06:48:27 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+gate2.bankerstrust.com - - [16/Oct/1997:06:48:28 -0700] "GET /comm/images/bluai.jpg HTTP/1.0" 200 11848+gate2.bankerstrust.com - - [16/Oct/1997:06:48:33 -0700] "GET /comm/images/bluspots.jpg HTTP/1.0" 200 18585+gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+gate2.bankerstrust.com - - [16/Oct/1997:06:48:39 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+gate2.bankerstrust.com - - [16/Oct/1997:06:48:41 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43+ppp44.igc.org - - [16/Oct/1997:06:49:12 -0700] "GET /regions/southern.html HTTP/1.0" 200 6455+palo1.pacific.net.sg - - [16/Oct/1997:06:49:13 -0700] "GET /amnesty/weeklyua.html HTTP/1.0" 200 10887+ppp44.igc.org - - [16/Oct/1997:06:49:15 -0700] "GET /regions/aiusared.gif HTTP/1.0" 200 2725+palo1.pacific.net.sg - - [16/Oct/1997:06:49:19 -0700] "GET /amnesty/images/logo2.gif HTTP/1.0" 200 6343+palo1.pacific.net.sg - - [16/Oct/1997:06:49:22 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+palo1.pacific.net.sg - - [16/Oct/1997:06:49:22 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+palo1.pacific.net.sg - - [16/Oct/1997:06:49:31 -0700] "GET /amnesty/images/linebrn.gif HTTP/1.0" 200 308+palo1.pacific.net.sg - - [16/Oct/1997:06:49:45 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+palo1.pacific.net.sg - - [16/Oct/1997:06:49:57 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+palo1.pacific.net.sg - - [16/Oct/1997:06:50:07 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+docrefoff5.library.emory.edu - - [16/Oct/1997:06:50:09 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+gate2.bankerstrust.com - - [16/Oct/1997:06:53:00 -0700] "GET /ainews/usa/spotward.html HTTP/1.0" 200 7907+gate2.bankerstrust.com - - [16/Oct/1997:06:53:12 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+ppp2200.stk.inreach.net - - [16/Oct/1997:06:54:21 -0700] "GET /cambodia/prosecut.html HTTP/1.0" 200 4764+1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:23 -0700] "GET /amnesty/turkey/back.gif HTTP/1.0" 200 224+1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:24 -0700] "GET /amnesty/turkey/women.html HTTP/1.0" 200 17534+1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:27 -0700] "GET /amnesty/turkey/amnty1.gif HTTP/1.0" 200 3013+1cust108.max41.los-angeles.ca.ms.uu.net - - [16/Oct/1997:06:55:27 -0700] "GET /amnesty/turkey/clear.gif HTTP/1.0" 200 76+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:57:33 -0700] "GET /amnesty/mideast/ HTTP/1.0" 200 3104+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:58:57 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:06:59:10 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682+194.165.130.7 - - [16/Oct/1997:06:59:34 -0700] "GET /amnesty/gan.html HTTP/1.0" 200 5020+194.165.130.7 - - [16/Oct/1997:06:59:39 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+194.165.130.7 - - [16/Oct/1997:06:59:39 -0700] "GET /amnesty/images/clear1.jpg HTTP/1.0" 200 849+194.165.130.7 - - [16/Oct/1997:06:59:43 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+194.165.130.7 - - [16/Oct/1997:06:59:44 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+194.165.130.7 - - [16/Oct/1997:06:59:47 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+194.165.130.7 - - [16/Oct/1997:07:00:14 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+194.165.130.7 - - [16/Oct/1997:07:00:19 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+194.165.130.7 - - [16/Oct/1997:07:00:20 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:00:20 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202+194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+194.165.130.7 - - [16/Oct/1997:07:00:27 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+194.165.130.7 - - [16/Oct/1997:07:00:31 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+194.165.130.7 - - [16/Oct/1997:07:00:33 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+194.165.130.7 - - [16/Oct/1997:07:00:35 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+194.165.130.7 - - [16/Oct/1997:07:00:37 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+194.165.130.7 - - [16/Oct/1997:07:00:37 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+194.165.130.7 - - [16/Oct/1997:07:00:40 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+194.165.130.7 - - [16/Oct/1997:07:00:42 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+194.165.130.7 - - [16/Oct/1997:07:00:43 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+194.165.130.7 - - [16/Oct/1997:07:00:45 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+194.165.130.7 - - [16/Oct/1997:07:00:54 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+ppp14.igc.org - - [16/Oct/1997:07:00:59 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+ppp14.igc.org - - [16/Oct/1997:07:00:59 -0700] "GET /images/writbut.gif HTTP/1.0" 200 543+ppp14.igc.org - - [16/Oct/1997:07:01:01 -0700] "GET /home.html HTTP/1.0" 200 17233+194.165.130.7 - - [16/Oct/1997:07:01:05 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+194.165.130.7 - - [16/Oct/1997:07:01:06 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+ppp14.igc.org - - [16/Oct/1997:07:01:06 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 3854+194.165.130.7 - - [16/Oct/1997:07:01:08 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+194.165.130.7 - - [16/Oct/1997:07:01:12 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+194.165.130.7 - - [16/Oct/1997:07:01:12 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:27 -0700] "GET /amnesty/mideast/counfram.html HTTP/1.0" 200 1145+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:58 -0700] "GET /amnesty/mideast/algeria.html HTTP/1.0" 200 7945+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:02:59 -0700] "GET /amnesty/mideast/algflag.gif HTTP/1.0" 200 1902+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:05 -0700] "GET /amnesty/mideast/algeria.jpg HTTP/1.0" 200 5485+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:10 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:11 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:12 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:13 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:21 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:30 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:30 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:31 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:32 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:34 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:34 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:35 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:03:35 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:04:19 -0700] "GET /amnesty/mideast/saudi.jpg HTTP/1.0" 200 8769+ppp14.igc.org - - [16/Oct/1997:07:04:48 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304+ppp14.igc.org - - [16/Oct/1997:07:04:51 -0700] "GET /images/picasso.gif HTTP/1.0" 200 1213+ppp14.igc.org - - [16/Oct/1997:07:04:55 -0700] "GET /images/women05.jpg HTTP/1.0" 200 10130+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:04:56 -0700] "GET /amnesty/mideast/sauflag.gif HTTP/1.0" 200 3101+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:07:33 -0700] "GET /amnesty/mideast/saudi.html HTTP/1.0" 200 8072+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:14:56 -0700] "GET /amnesty/mideast/oman.jpg HTTP/1.0" 200 4371+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:14 -0700] "GET /amnesty/mideast/omanflag.gif HTTP/1.0" 200 2012+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:22 -0700] "GET /amnesty/mideast/gulf.html HTTP/1.0" 200 10736+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:23 -0700] "GET /amnesty/mideast/qatflag.gif HTTP/1.0" 200 1456+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:28 -0700] "GET /amnesty/mideast/qatar.jpg HTTP/1.0" 200 4615+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:29 -0700] "GET /amnesty/mideast/uaeflag.gif HTTP/1.0" 200 1725+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:15:42 -0700] "GET /amnesty/mideast/uae.jpg HTTP/1.0" 200 13752+168.30.243.210 - - [16/Oct/1997:07:18:52 -0700] "GET /amnesty/asa/china/images/animai.gif HTTP/1.0" 200 5175+168.30.243.210 - - [16/Oct/1997:07:18:52 -0700] "GET /amnesty/asa/china/images/smflag.gif HTTP/1.0" 200 951+168.30.243.210 - - [16/Oct/1997:07:18:53 -0700] "GET /amnesty/asa/china/chinese.html HTTP/1.0" 200 15983+168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/mail8380.gif HTTP/1.0" 200 4196+168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/tibet.gif HTTP/1.0" 200 1241+168.30.243.210 - - [16/Oct/1997:07:18:54 -0700] "GET /amnesty/asa/china/images/xj.gif HTTP/1.0" 200 1247+168.30.243.210 - - [16/Oct/1997:07:18:55 -0700] "GET /amnesty/asa/china/images/aichico.gif HTTP/1.0" 200 4724+168.30.243.210 - - [16/Oct/1997:07:18:55 -0700] "GET /amnesty/asa/china/images/hk.gif HTTP/1.0" 200 1212+168.30.243.210 - - [16/Oct/1997:07:18:56 -0700] "GET /amnesty/asa/china/images/mailbox1.gif HTTP/1.0" 200 17344+ppp6-12.igc.org - - [16/Oct/1997:07:19:27 -0700] "GET / HTTP/1.0" 200 3082+ppp6-12.igc.org - - [16/Oct/1997:07:19:28 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+ppp6-12.igc.org - - [16/Oct/1997:07:19:40 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:22:01 -0700] "GET /amnesty/mideast/uaemona.html HTTP/1.0" 200 2200+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:22:59 -0700] "GET /amnesty/mideast/bahrain.html HTTP/1.0" 200 11354+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:23:01 -0700] "GET /amnesty/mideast/bahflag.gif HTTP/1.0" 200 1505+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:23:01 -0700] "GET /amnesty/mideast/bahrain.jpg HTTP/1.0" 200 5547+tbm-jjs.caen.cnet.fr - - [16/Oct/1997:07:24:13 -0700] "GET /amnesty/mideast/region.html HTTP/1.0" 200 1049+ppp22.igc.org - - [16/Oct/1997:07:27:23 -0700] "GET / HTTP/1.0" 200 3082+ppp22.igc.org - - [16/Oct/1997:07:27:26 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+ppp22.igc.org - - [16/Oct/1997:07:27:29 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ppp22.igc.org - - [16/Oct/1997:07:27:39 -0700] "GET /joinai.html HTTP/1.0" 200 4054+ppp22.igc.org - - [16/Oct/1997:07:27:41 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+ppp22.igc.org - - [16/Oct/1997:07:27:41 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+ppp22.igc.org - - [16/Oct/1997:07:27:42 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+ppp22.igc.org - - [16/Oct/1997:07:27:42 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+ppp22.igc.org - - [16/Oct/1997:07:27:44 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+ppp22.igc.org - - [16/Oct/1997:07:27:44 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+ppp22.igc.org - - [16/Oct/1997:07:28:12 -0700] "GET /amnesty HTTP/1.0" 301 184+ppp22.igc.org - - [16/Oct/1997:07:28:15 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ppp22.igc.org - - [16/Oct/1997:07:28:17 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ppp22.igc.org - - [16/Oct/1997:07:28:20 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ppp22.igc.org - - [16/Oct/1997:07:29:36 -0700] "GET /welcome.html HTTP/1.0" 200 4731+ppp22.igc.org - - [16/Oct/1997:07:29:39 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+ppp22.igc.org - - [16/Oct/1997:07:29:39 -0700] "GET /images/never.gif HTTP/1.0" 200 914+ppp22.igc.org - - [16/Oct/1997:07:29:41 -0700] "GET /images/doubt.gif HTTP/1.0" 200 924+ppp22.igc.org - - [16/Oct/1997:07:29:43 -0700] "GET /images/your.gif HTTP/1.0" 200 951+ppp22.igc.org - - [16/Oct/1997:07:29:44 -0700] "GET /images/commit.gif HTTP/1.0" 200 190+ppp22.igc.org - - [16/Oct/1997:07:29:46 -0700] "GET /images/human.gif HTTP/1.0" 200 155+ppp22.igc.org - - [16/Oct/1997:07:29:46 -0700] "GET /images/refugee2.gif HTTP/1.0" 200 14882+ppp22.igc.org - - [16/Oct/1997:07:29:48 -0700] "GET /images/can.gif HTTP/1.0" 200 946+ppp22.igc.org - - [16/Oct/1997:07:29:48 -0700] "GET /images/rights.gif HTTP/1.0" 200 938+ppp22.igc.org - - [16/Oct/1997:07:29:49 -0700] "GET /images/a.gif HTTP/1.0" 200 865+ppp22.igc.org - - [16/Oct/1997:07:29:49 -0700] "GET /images/differ.gif HTTP/1.0" 200 191+ppp22.igc.org - - [16/Oct/1997:07:29:50 -0700] "GET /images/it.gif HTTP/1.0" 200 170+ppp22.igc.org - - [16/Oct/1997:07:29:51 -0700] "GET /images/canred.gif HTTP/1.0" 200 311+ppp22.igc.org - - [16/Oct/1997:07:29:52 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+ppp22.igc.org - - [16/Oct/1997:07:29:54 -0700] "GET /images/3ways.gif HTTP/1.0" 200 1157+ppp22.igc.org - - [16/Oct/1997:07:29:57 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+ppp22.igc.org - - [16/Oct/1997:07:29:58 -0700] "GET /images/aiusabut.gif HTTP/1.0" 200 591+ppp22.igc.org - - [16/Oct/1997:07:30:05 -0700] "GET /images/mombab10.gif HTTP/1.0" 200 28581+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:56 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:57 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:36:58 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:06 -0700] "GET /amnesty/comm/medaward.html HTTP/1.0" 200 6483+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/comm/images/starblu.jpg HTTP/1.0" 200 5498+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:08 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:10 -0700] "GET /amnesty/comm/images/bluai.jpg HTTP/1.0" 200 11848+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:10 -0700] "GET /amnesty/comm/images/bluspots.jpg HTTP/1.0" 200 18585+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:33 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:34 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:35 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:36 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:37 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:37 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:38 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:38 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:37:43 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+pm3-138.lex.infi.net - - [16/Oct/1997:07:38:19 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+pm3-138.lex.infi.net - - [16/Oct/1997:07:38:25 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+pm3-138.lex.infi.net - - [16/Oct/1997:07:38:27 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+pm3-138.lex.infi.net - - [16/Oct/1997:07:38:53 -0700] "GET /amnesty/images/usstamp.gif HTTP/1.0" 200 6166+pm3-138.lex.infi.net - - [16/Oct/1997:07:38:53 -0700] "GET /amnesty/write.html HTTP/1.0" 200 9408+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:00 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:01 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:03 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+pm3-138.lex.infi.net - - [16/Oct/1997:07:39:03 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+rm122a.flhigh.fsu.edu - - [16/Oct/1997:07:40:08 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+pm3-138.lex.infi.net - - [16/Oct/1997:07:40:37 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+pm3-138.lex.infi.net - - [16/Oct/1997:07:40:50 -0700] "GET /amnesty/whatsnew.html HTTP/1.0" 200 7562+pm3-138.lex.infi.net - - [16/Oct/1997:07:40:51 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+pm3-138.lex.infi.net - - [16/Oct/1997:07:40:52 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+pm3-138.lex.infi.net - - [16/Oct/1997:07:41:44 -0700] "GET /amnesty/asa/china/torgeson.html HTTP/1.0" 200 1862+pm3-138.lex.infi.net - - [16/Oct/1997:07:41:47 -0700] "GET /amnesty/asa/china/images/marble3.jpg HTTP/1.0" 200 2518+pm3-138.lex.infi.net - - [16/Oct/1997:07:42:02 -0700] "GET /amnesty/asa/china/images/wall.jpg HTTP/1.0" 200 16469+pm3-138.lex.infi.net - - [16/Oct/1997:07:42:19 -0700] "GET /amnesty/asa/china/images/kris.jpg HTTP/1.0" 200 37521+pm3-138.lex.infi.net - - [16/Oct/1997:07:42:32 -0700] "GET /amnesty/asa/china/images/read.gif HTTP/1.0" 200 13330+spo27.homeshopping.com.br - - [16/Oct/1997:07:42:58 -0700] "GET / HTTP/1.0" 200 3082+spo27.homeshopping.com.br - - [16/Oct/1997:07:43:00 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+pm3-138.lex.infi.net - - [16/Oct/1997:07:43:04 -0700] "GET /amnesty/asa/china/louisa-links.html HTTP/1.0" 200 1076+spo27.homeshopping.com.br - - [16/Oct/1997:07:43:06 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+spo27.homeshopping.com.br - - [16/Oct/1997:07:43:11 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+128.146.150.29 - - [16/Oct/1997:07:43:13 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+128.146.150.29 - - [16/Oct/1997:07:43:14 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+128.146.150.29 - - [16/Oct/1997:07:43:15 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+204.183.72.198 - - [16/Oct/1997:07:45:28 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887+204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+204.183.72.198 - - [16/Oct/1997:07:45:29 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+204.183.72.198 - - [16/Oct/1997:07:45:30 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+204.183.72.198 - - [16/Oct/1997:07:45:30 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+204.183.72.198 - - [16/Oct/1997:07:45:31 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+204.183.72.198 - - [16/Oct/1997:07:45:31 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+204.183.72.198 - - [16/Oct/1997:07:45:32 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308+204.183.72.198 - - [16/Oct/1997:07:46:44 -0700] "GET /urgact/ HTTP/1.0" 200 8283+207.38.218.82 - - [16/Oct/1997:07:46:50 -0700] "GET /amnesty HTTP/1.0" 301 184+207.38.218.82 - - [16/Oct/1997:07:46:51 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+207.38.218.82 - - [16/Oct/1997:07:46:53 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+207.38.218.82 - - [16/Oct/1997:07:46:54 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:18 -0700] "GET /turkey/back.gif HTTP/1.0" 200 224+171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:22 -0700] "GET /turkey/clear.gif HTTP/1.0" 200 76+171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:23 -0700] "GET /turkey/amnty1.gif HTTP/1.0" 200 3013+171-164-127.ipt.aol.com - - [16/Oct/1997:07:47:31 -0700] "GET /turkey/women.html HTTP/1.0" 200 17534+207.38.218.82 - - [16/Oct/1997:07:48:08 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+207.38.218.82 - - [16/Oct/1997:07:48:10 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+207.38.218.82 - - [16/Oct/1997:07:48:11 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+207.38.218.82 - - [16/Oct/1997:07:48:13 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+207.38.218.82 - - [16/Oct/1997:07:48:15 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+207.38.218.82 - - [16/Oct/1997:07:48:19 -0700] "GET /amnesty/images/hometake.gif HTTP/1.0" 200 1367+207.38.218.82 - - [16/Oct/1997:07:48:19 -0700] "GET /amnesty/images/writbut.gif HTTP/1.0" 200 543+207.38.218.82 - - [16/Oct/1997:07:48:20 -0700] "GET /amnesty/home.html HTTP/1.0" 200 17233+207.38.218.82 - - [16/Oct/1997:07:48:21 -0700] "GET /amnesty/images/homelogo.gif HTTP/1.0" 200 11841+207.38.218.82 - - [16/Oct/1997:07:48:21 -0700] "GET /amnesty/images/pubbut.gif HTTP/1.0" 200 1291+207.38.218.82 - - [16/Oct/1997:07:48:22 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+207.38.218.82 - - [16/Oct/1997:07:48:24 -0700] "GET /amnesty/images/rsacirat.gif HTTP/1.0" 200 2021+207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/eventbut.gif HTTP/1.0" 200 380+207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/joinbut2.gif HTTP/1.0" 200 362+207.38.218.82 - - [16/Oct/1997:07:48:25 -0700] "GET /amnesty/images/savebutx.gif HTTP/1.0" 200 889+207.38.218.82 - - [16/Oct/1997:07:48:26 -0700] "GET /amnesty/images/countbut.gif HTTP/1.0" 200 1673+207.38.218.82 - - [16/Oct/1997:07:48:26 -0700] "GET /amnesty/images/spanbut.gif HTTP/1.0" 200 447+207.38.218.82 - - [16/Oct/1997:07:48:27 -0700] "GET /amnesty/images/getbut.gif HTTP/1.0" 200 2482+207.38.218.82 - - [16/Oct/1997:07:48:27 -0700] "GET /amnesty/images/membutx.gif HTTP/1.0" 200 849+207.38.218.82 - - [16/Oct/1997:07:48:28 -0700] "GET /amnesty/images/homenew.gif HTTP/1.0" 200 1493+207.38.218.82 - - [16/Oct/1997:07:48:29 -0700] "GET /amnesty/images/homeside.gif HTTP/1.0" 200 1612+207.38.218.82 - - [16/Oct/1997:07:48:34 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731+207.38.218.82 - - [16/Oct/1997:07:48:37 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924+207.38.218.82 - - [16/Oct/1997:07:48:37 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914+207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/commit.gif HTTP/1.0" 200 190+207.38.218.82 - - [16/Oct/1997:07:48:38 -0700] "GET /amnesty/images/rights.gif HTTP/1.0" 200 938+207.38.218.82 - - [16/Oct/1997:07:48:39 -0700] "GET /amnesty/images/a.gif HTTP/1.0" 200 865+207.38.218.82 - - [16/Oct/1997:07:48:40 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 14882+207.38.218.82 - - [16/Oct/1997:07:48:41 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+207.38.218.82 - - [16/Oct/1997:07:48:41 -0700] "GET /amnesty/images/canred.gif HTTP/1.0" 200 311+207.38.218.82 - - [16/Oct/1997:07:48:42 -0700] "GET /amnesty/images/your.gif HTTP/1.0" 200 951+207.38.218.82 - - [16/Oct/1997:07:48:43 -0700] "GET /amnesty/images/differ.gif HTTP/1.0" 200 191+207.38.218.82 - - [16/Oct/1997:07:48:43 -0700] "GET /amnesty/images/human.gif HTTP/1.0" 200 155+207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/3ways.gif HTTP/1.0" 200 1157+207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/can.gif HTTP/1.0" 200 946+207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/it.gif HTTP/1.0" 200 170+207.38.218.82 - - [16/Oct/1997:07:48:44 -0700] "GET /amnesty/images/wamwer6.jpg HTTP/1.0" 200 9786+207.38.218.82 - - [16/Oct/1997:07:48:45 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 200 591+207.38.218.82 - - [16/Oct/1997:07:48:48 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 200 16384+207.38.218.82 - - [16/Oct/1997:07:48:54 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 304 -+207.38.218.82 - - [16/Oct/1997:07:48:54 -0700] "GET /amnesty/welcome.html HTTP/1.0" 304 -+207.38.218.82 - - [16/Oct/1997:07:48:55 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 304 -+207.38.218.82 - - [16/Oct/1997:07:48:56 -0700] "GET /amnesty/images/aiusabut.gif HTTP/1.0" 206 318+207.38.218.82 - - [16/Oct/1997:07:49:03 -0700] "GET /amnesty/images/mombab10.gif HTTP/1.0" 206 14999+207.38.218.82 - - [16/Oct/1997:07:50:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+207.38.218.82 - - [16/Oct/1997:07:50:29 -0700] "GET /amnesty/joinai.html HTTP/1.0" 304 -+207.38.218.82 - - [16/Oct/1997:07:50:30 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+208.133.54.8 - - [16/Oct/1997:07:51:45 -0700] "GET / HTTP/1.0" 200 3082+208.133.54.8 - - [16/Oct/1997:07:51:46 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+208.133.54.8 - - [16/Oct/1997:07:51:49 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+208.133.54.8 - - [16/Oct/1997:07:51:50 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+208.133.54.8 - - [16/Oct/1997:07:52:02 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+208.133.54.8 - - [16/Oct/1997:07:52:02 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+208.133.54.8 - - [16/Oct/1997:07:52:03 -0700] "GET /ainews.html HTTP/1.0" 200 13435+208.133.54.8 - - [16/Oct/1997:07:52:04 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+208.133.54.8 - - [16/Oct/1997:07:52:04 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+208.133.54.8 - - [16/Oct/1997:07:52:05 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+208.133.54.8 - - [16/Oct/1997:07:52:05 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+208.133.54.8 - - [16/Oct/1997:07:52:06 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+208.133.54.8 - - [16/Oct/1997:07:52:07 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+208.133.54.8 - - [16/Oct/1997:07:52:07 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+208.133.54.8 - - [16/Oct/1997:07:52:08 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+208.133.54.8 - - [16/Oct/1997:07:52:57 -0700] "GET /peru/aatiger.html HTTP/1.0" 200 10330+208.133.54.8 - - [16/Oct/1997:07:52:58 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+208.133.54.8 - - [16/Oct/1997:07:53:15 -0700] "GET /peru/peru.html HTTP/1.0" 200 12264+207.8.177.135 - - [16/Oct/1997:07:55:41 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+207.8.177.135 - - [16/Oct/1997:07:55:55 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+207.8.177.135 - - [16/Oct/1997:07:56:02 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+207.8.177.135 - - [16/Oct/1997:07:56:14 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+207.8.177.135 - - [16/Oct/1997:07:56:17 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+207.8.177.135 - - [16/Oct/1997:07:56:20 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+207.8.177.135 - - [16/Oct/1997:07:56:23 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+207.8.177.135 - - [16/Oct/1997:07:56:23 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+207.8.177.135 - - [16/Oct/1997:07:56:25 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+207.8.177.135 - - [16/Oct/1997:07:56:26 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+207.8.177.135 - - [16/Oct/1997:07:56:26 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+207.8.177.135 - - [16/Oct/1997:07:56:29 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+207.8.177.135 - - [16/Oct/1997:07:56:29 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+207.8.177.135 - - [16/Oct/1997:07:56:30 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+207.8.177.135 - - [16/Oct/1997:07:56:34 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+207.8.177.135 - - [16/Oct/1997:07:56:38 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+207.8.177.135 - - [16/Oct/1997:07:56:41 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+207.8.177.135 - - [16/Oct/1997:07:56:41 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+207.8.177.135 - - [16/Oct/1997:07:56:47 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+pm3-138.lex.infi.net - - [16/Oct/1997:07:56:52 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+207.8.177.135 - - [16/Oct/1997:07:56:52 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+207.8.177.135 - - [16/Oct/1997:07:56:54 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+207.8.177.135 - - [16/Oct/1997:07:56:54 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+207.8.177.135 - - [16/Oct/1997:07:57:00 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+207.8.177.135 - - [16/Oct/1997:07:57:00 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+pm3-138.lex.infi.net - - [16/Oct/1997:07:57:18 -0700] "GET /amnesty/welcome.html HTTP/1.0" 200 4731+pm3-138.lex.infi.net - - [16/Oct/1997:07:57:20 -0700] "GET /amnesty/images/never.gif HTTP/1.0" 200 914+pm3-138.lex.infi.net - - [16/Oct/1997:07:57:21 -0700] "GET /amnesty/images/doubt.gif HTTP/1.0" 200 924+207.8.177.135 - - [16/Oct/1997:07:57:27 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+207.8.177.135 - - [16/Oct/1997:07:57:27 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+207.8.177.135 - - [16/Oct/1997:07:57:28 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+207.8.177.135 - - [16/Oct/1997:07:57:58 -0700] "GET /amnesty/joinai.txt HTTP/1.0" 200 1914+207.8.177.135 - - [16/Oct/1997:07:58:23 -0700] "GET /amnesty/vgroups.html HTTP/1.0" 200 4391+207.8.177.135 - - [16/Oct/1997:07:58:25 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+207.8.177.135 - - [16/Oct/1997:07:58:26 -0700] "GET /amnesty/images/groucont.gif HTTP/1.0" 200 669+207.8.177.135 - - [16/Oct/1997:07:58:26 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+207.8.177.135 - - [16/Oct/1997:07:58:29 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+207.8.177.135 - - [16/Oct/1997:07:58:42 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575+207.8.177.135 - - [16/Oct/1997:07:58:44 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161+207.8.177.135 - - [16/Oct/1997:07:58:46 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013+207.8.177.135 - - [16/Oct/1997:07:58:47 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257+207.8.177.135 - - [16/Oct/1997:07:58:47 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471+207.8.177.135 - - [16/Oct/1997:07:58:49 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+207.8.177.135 - - [16/Oct/1997:07:58:53 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+207.8.177.135 - - [16/Oct/1997:07:58:53 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399+207.8.177.135 - - [16/Oct/1997:07:58:59 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430+207.8.177.135 - - [16/Oct/1997:07:59:01 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+207.8.177.135 - - [16/Oct/1997:07:59:07 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+207.8.177.135 - - [16/Oct/1997:07:59:08 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+207.8.177.135 - - [16/Oct/1997:07:59:14 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+204.232.49.30 - - [16/Oct/1997:07:59:37 -0700] "GET / HTTP/1.0" 200 3082+204.232.49.30 - - [16/Oct/1997:07:59:38 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+204.232.49.30 - - [16/Oct/1997:07:59:38 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+204.232.49.30 - - [16/Oct/1997:07:59:49 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562+204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/homenew.gif HTTP/1.0" 200 1493+204.232.49.30 - - [16/Oct/1997:07:59:50 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+204.232.49.30 - - [16/Oct/1997:07:59:51 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+158.5.27.50 - - [16/Oct/1997:07:59:52 -0700] "GET /amnesty/mideast/iraqar.html HTTP/1.0" 200 15153+204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+204.232.49.30 - - [16/Oct/1997:07:59:52 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+204.232.49.30 - - [16/Oct/1997:08:00:16 -0700] "GET /images/homelogo.gif HTTP/1.0" 200 11841+204.232.49.30 - - [16/Oct/1997:08:00:16 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+204.232.49.30 - - [16/Oct/1997:08:00:17 -0700] "GET /images/hometake.gif HTTP/1.0" 200 1367+204.232.49.30 - - [16/Oct/1997:08:00:18 -0700] "GET /home.html HTTP/1.0" 200 17233+204.232.49.30 - - [16/Oct/1997:08:00:18 -0700] "GET /images/homeside.gif HTTP/1.0" 200 1612+204.232.49.30 - - [16/Oct/1997:08:00:20 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/joinbut2.gif HTTP/1.0" 200 362+204.232.49.30 - - [16/Oct/1997:08:00:21 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/getbut.gif HTTP/1.0" 200 2482+204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/savebutx.gif HTTP/1.0" 200 889+204.232.49.30 - - [16/Oct/1997:08:00:22 -0700] "GET /images/spanbut.gif HTTP/1.0" 200 447+204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+204.232.49.30 - - [16/Oct/1997:08:00:23 -0700] "GET /images/rsacirat.gif HTTP/1.0" 200 2021+204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/membutx.gif HTTP/1.0" 200 849+204.232.49.30 - - [16/Oct/1997:08:00:24 -0700] "GET /images/pnbut.gif HTTP/1.0" 200 670+204.232.49.30 - - [16/Oct/1997:08:00:25 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+204.232.49.30 - - [16/Oct/1997:08:00:28 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166+204.232.49.30 - - [16/Oct/1997:08:00:28 -0700] "GET /write.html HTTP/1.0" 200 9408+204.232.49.30 - - [16/Oct/1997:08:00:52 -0700] "GET / HTTP/1.0" 200 -+204.232.49.30 - - [16/Oct/1997:08:00:53 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+204.232.49.30 - - [16/Oct/1997:08:00:53 -0700] "GET /images/spot5.gif HTTP/1.0" 304 -+208.226.16.80 - - [16/Oct/1997:08:00:57 -0700] "GET / HTTP/1.0" 200 3082+204.232.49.30 - - [16/Oct/1997:08:00:58 -0700] "GET /write.html HTTP/1.0" 200 9408+204.232.49.30 - - [16/Oct/1997:08:00:59 -0700] "GET /images/usstamp.gif HTTP/1.0" 200 6166+204.232.49.30 - - [16/Oct/1997:08:01:00 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:01:01 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+208.226.16.80 - - [16/Oct/1997:08:01:39 -0700] "GET / HTTP/1.0" 200 3082+204.232.49.30 - - [16/Oct/1997:08:02:11 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308+204.232.49.30 - - [16/Oct/1997:08:02:11 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+204.232.49.30 - - [16/Oct/1997:08:02:12 -0700] "GET /weeklyua.html HTTP/1.0" 200 10887+208.226.16.80 - - [16/Oct/1997:08:02:40 -0700] "GET / HTTP/1.0" 200 3082+208.226.16.80 - - [16/Oct/1997:08:02:45 -0700] "GET / HTTP/1.0" 200 3082+pm3-138.lex.infi.net - - [16/Oct/1997:08:04:03 -0700] "GET /amnesty/images/refugee2.gif HTTP/1.0" 200 9230+204.232.49.30 - - [16/Oct/1997:08:04:17 -0700] "GET /joinai.html HTTP/1.0" 200 4054+204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+204.232.49.30 - - [16/Oct/1997:08:04:18 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+204.232.49.30 - - [16/Oct/1997:08:04:19 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.232.49.30 - - [16/Oct/1997:08:04:20 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+ad20-094.compuserve.com - - [16/Oct/1997:08:04:39 -0700] "GET /amnesty/mideast/countrie.html HTTP/1.0" 200 1527+ad20-094.compuserve.com - - [16/Oct/1997:08:04:43 -0700] "GET /amnesty/mideast/butalg.gif HTTP/1.0" 200 368+ad20-094.compuserve.com - - [16/Oct/1997:08:04:55 -0700] "GET /amnesty/mideast/butbah.gif HTTP/1.0" 200 380+ad20-094.compuserve.com - - [16/Oct/1997:08:04:59 -0700] "GET /amnesty/mideast/butegy.gif HTTP/1.0" 200 363+ad20-094.compuserve.com - - [16/Oct/1997:08:04:59 -0700] "GET /amnesty/mideast/butgul.gif HTTP/1.0" 200 399+ad20-094.compuserve.com - - [16/Oct/1997:08:05:02 -0700] "GET /amnesty/mideast/butirq.gif HTTP/1.0" 200 329+ad20-094.compuserve.com - - [16/Oct/1997:08:05:04 -0700] "GET /amnesty/mideast/butjor.gif HTTP/1.0" 200 352+ad20-094.compuserve.com - - [16/Oct/1997:08:05:06 -0700] "GET /amnesty/mideast/butirn.gif HTTP/1.0" 200 317+ad20-094.compuserve.com - - [16/Oct/1997:08:05:06 -0700] "GET /amnesty/mideast/butisr.gif HTTP/1.0" 200 384+ad20-094.compuserve.com - - [16/Oct/1997:08:05:09 -0700] "GET /amnesty/mideast/butleb.gif HTTP/1.0" 200 383+ad20-094.compuserve.com - - [16/Oct/1997:08:05:11 -0700] "GET /amnesty/mideast/butlib.gif HTTP/1.0" 200 352+204.232.49.30 - - [16/Oct/1997:08:05:12 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+ad20-094.compuserve.com - - [16/Oct/1997:08:05:12 -0700] "GET /amnesty/mideast/butsau.gif HTTP/1.0" 200 403+ad20-094.compuserve.com - - [16/Oct/1997:08:05:13 -0700] "GET /amnesty/mideast/butkuw.gif HTTP/1.0" 200 366+204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+204.232.49.30 - - [16/Oct/1997:08:05:13 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+ad20-094.compuserve.com - - [16/Oct/1997:08:05:14 -0700] "GET /amnesty/mideast/butmor.gif HTTP/1.0" 200 432+204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+204.232.49.30 - - [16/Oct/1997:08:05:14 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+204.232.49.30 - - [16/Oct/1997:08:05:15 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+ad20-094.compuserve.com - - [16/Oct/1997:08:05:16 -0700] "GET /amnesty/mideast/butsyr.gif HTTP/1.0" 200 344+204.232.49.30 - - [16/Oct/1997:08:05:17 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+204.232.49.30 - - [16/Oct/1997:08:05:17 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+ad20-094.compuserve.com - - [16/Oct/1997:08:05:18 -0700] "GET /amnesty/mideast/buttun.gif HTTP/1.0" 200 359+204.232.49.30 - - [16/Oct/1997:08:05:18 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+ad20-094.compuserve.com - - [16/Oct/1997:08:05:19 -0700] "GET /amnesty/mideast/butbac.gif HTTP/1.0" 200 592+ad20-094.compuserve.com - - [16/Oct/1997:08:05:19 -0700] "GET /amnesty/mideast/butyem.gif HTTP/1.0" 200 352+204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+204.232.49.30 - - [16/Oct/1997:08:05:19 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+204.232.49.30 - - [16/Oct/1997:08:05:20 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+204.232.49.30 - - [16/Oct/1997:08:05:21 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+204.232.49.30 - - [16/Oct/1997:08:05:25 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+ad20-094.compuserve.com - - [16/Oct/1997:08:05:35 -0700] "GET /amnesty/mideast/saudi.html HTTP/1.0" 200 8072+ad20-094.compuserve.com - - [16/Oct/1997:08:05:35 -0700] "GET /amnesty/mideast/sauflag.gif HTTP/1.0" 200 3101+204.232.49.30 - - [16/Oct/1997:08:05:46 -0700] "GET /about.html HTTP/1.0" 200 6902+ad20-094.compuserve.com - - [16/Oct/1997:08:05:46 -0700] "GET /amnesty/mideast/mailbut2.gif HTTP/1.0" 200 1202+204.232.49.30 - - [16/Oct/1997:08:05:47 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+204.232.49.30 - - [16/Oct/1997:08:05:48 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+204.232.49.30 - - [16/Oct/1997:08:05:49 -0700] "GET /images/where.gif HTTP/1.0" 200 605+ad20-094.compuserve.com - - [16/Oct/1997:08:05:52 -0700] "GET /amnesty/mideast/saudi.jpg HTTP/1.0" 200 8769+204.232.49.30 - - [16/Oct/1997:08:06:10 -0700] "GET /ainews.html HTTP/1.0" 200 13435+204.232.49.30 - - [16/Oct/1997:08:06:10 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+204.232.49.30 - - [16/Oct/1997:08:06:11 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+204.232.49.30 - - [16/Oct/1997:08:06:12 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+204.232.49.30 - - [16/Oct/1997:08:06:12 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+204.232.49.30 - - [16/Oct/1997:08:06:13 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+204.232.49.30 - - [16/Oct/1997:08:06:13 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+208.226.16.80 - - [16/Oct/1997:08:06:20 -0700] "GET / HTTP/1.0" 200 3082+204.232.49.30 - - [16/Oct/1997:08:06:29 -0700] "GET /ainews/china/execrec.html HTTP/1.0" 200 6897+204.232.49.30 - - [16/Oct/1997:08:06:30 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:22 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:23 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:28 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+doe-190-9.lib.berkeley.edu - - [16/Oct/1997:08:07:39 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ad20-094.compuserve.com - - [16/Oct/1997:08:08:20 -0700] "GET /amnesty/mideast/moroc.html HTTP/1.0" 200 6539+ad20-094.compuserve.com - - [16/Oct/1997:08:08:24 -0700] "GET /amnesty/mideast/morflag.gif HTTP/1.0" 200 1680+ad20-094.compuserve.com - - [16/Oct/1997:08:09:09 -0700] "GET /amnesty/mideast/morws.jpg HTTP/1.0" 200 17585+ppp4-35.igc.org - - [16/Oct/1997:08:11:14 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:14 -0700] "GET /images/hometake.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:15 -0700] "GET /home.html HTTP/1.0" 200 17233+ppp4-35.igc.org - - [16/Oct/1997:08:11:15 -0700] "GET /images/writbut.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:16 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:16 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:17 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:17 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:19 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/homenew.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/homeside.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:20 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:21 -0700] "GET /whatsnew.html HTTP/1.0" 200 7562+ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/aiusared.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:23 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:24 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:24 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:26 -0700] "GET /regions/index.html HTTP/1.0" 200 2312+ppp4-35.igc.org - - [16/Oct/1997:08:11:27 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:33 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304+ppp4-35.igc.org - - [16/Oct/1997:08:11:34 -0700] "GET /images/picasso.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:11:34 -0700] "GET /images/women05.jpg HTTP/1.0" 304 -+ad20-094.compuserve.com - - [16/Oct/1997:08:11:38 -0700] "GET /amnesty/mideast/index.html HTTP/1.0" 200 3104+ad20-094.compuserve.com - - [16/Oct/1997:08:11:47 -0700] "GET /amnesty/mideast/ailogo.gif HTTP/1.0" 200 2682+ad20-094.compuserve.com - - [16/Oct/1997:08:12:09 -0700] "GET /amnesty/mideast/hrme.jpg HTTP/1.0" 200 24216+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:39 -0700] "GET /amnesty HTTP/1.0" 301 184+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:40 -0700] "GET /amnesty/ HTTP/1.0" 200 3082+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:43 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:12:45 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:13 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:16 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:18 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:19 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:20 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:22 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:24 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:24 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:25 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:25 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:27 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:30 -0700] "GET /amnesty/abolish/index.html HTTP/1.0" 200 6318+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:33 -0700] "GET /amnesty/images/aiusared.gif HTTP/1.0" 200 2725+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:34 -0700] "GET /amnesty/images/dot_clea.gif HTTP/1.0" 200 43+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:35 -0700] "GET /amnesty/abolish/images/clock6.gif HTTP/1.0" 200 11949+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/abolish/images/clock4.gif HTTP/1.0" 200 37947+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:37 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:39 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:41 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+p03-54.onyx.net - - [16/Oct/1997:08:13:44 -0700] "GET /amnesty/ai_gloss.html HTTP/1.0" 200 6214+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:46 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+p03-54.onyx.net - - [16/Oct/1997:08:13:47 -0700] "GET /amnesty/images/amnesty.gif HTTP/1.0" 200 1158+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:13:58 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:05 -0700] "GET /amnesty/abolish/dpfacts.html HTTP/1.0" 200 14087+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:06 -0700] "GET /amnesty/abolish/images/greysand.gif HTTP/1.0" 200 10546+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:09 -0700] "GET /amnesty/images/blkcnd2x.gif HTTP/1.0" 200 1439+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:11 -0700] "GET /amnesty/abolish/images/airedsnd.gif HTTP/1.0" 200 8856+p03-54.onyx.net - - [16/Oct/1997:08:14:12 -0700] "GET /amnesty/regions.html HTTP/1.0" 200 4886+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:15 -0700] "GET /amnesty/images/deathbux.gif HTTP/1.0" 200 1667+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:27 -0700] "GET /amnesty/abolish/8'5uaup.html HTTP/1.0" 200 4586+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:30 -0700] "GET /amnesty/tools/dot_clea.gif HTTP/1.0" 200 43+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:30 -0700] "GET /amnesty/tools/ffffff.gif HTTP/1.0" 200 35+p03-54.onyx.net - - [16/Oct/1997:08:14:42 -0700] "GET /amnesty/index.html HTTP/1.0" 200 3082+p03-54.onyx.net - - [16/Oct/1997:08:14:45 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+p03-54.onyx.net - - [16/Oct/1997:08:14:48 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 200 9372+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:14:54 -0700] "GET /amnesty/abolish/executio.html HTTP/1.0" 200 5523+p03-54.onyx.net - - [16/Oct/1997:08:14:56 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+p03-54.onyx.net - - [16/Oct/1997:08:15:24 -0700] "GET /amnesty/joinai.html HTTP/1.0" 200 4054+ww-tr03.proxy.aol.com - - [16/Oct/1997:08:15:47 -0700] "GET /amnesty/abolish/leavrick.html HTTP/1.0" 200 1585+hera-18.hermesnet.net - - [16/Oct/1997:08:18:45 -0700] "GET / HTTP/1.0" 200 3082+hera-18.hermesnet.net - - [16/Oct/1997:08:18:49 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+hera-18.hermesnet.net - - [16/Oct/1997:08:18:52 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:23 -0700] "GET /amnesty/index.html HTTP/1.0" 200 3082+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:32 -0700] "GET /amnesty/images/bsilk7.gif HTTP/1.0" 404 178+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:33 -0700] "GET /amnesty/images/spot5.gif HTTP/1.0" 304 -+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:42 -0700] "GET /amnesty/aicapn2.html HTTP/1.0" 200 12769+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:44 -0700] "GET /amnesty/images/campbut.gif HTTP/1.0" 200 1257+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/dot.gif HTTP/1.0" 200 946+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/ganbut.gif HTTP/1.0" 200 1414+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/pandnlog.gif HTTP/1.0" 200 15944+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:45 -0700] "GET /amnesty/images/refbut.gif HTTP/1.0" 200 1182+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/deathbut.gif HTTP/1.0" 200 1310+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/groupbut.gif HTTP/1.0" 200 1173+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/lgbut.gif HTTP/1.0" 200 614+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/ncasebut.gif HTTP/1.0" 200 1427+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:53 -0700] "GET /amnesty/images/uabut.gif HTTP/1.0" 200 1288+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:56 -0700] "GET /amnesty/images/healbut.gif HTTP/1.0" 200 1492+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:56 -0700] "GET /amnesty/images/legalbut.gif HTTP/1.0" 200 1097+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/educbut.gif HTTP/1.0" 200 1246+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:57 -0700] "GET /amnesty/images/wordo35d.gif HTTP/1.0" 200 7089+nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:20:57 -0700] "GET /comm/herbert.html HTTP/1.0" 200 1563+ww-to03.proxy.aol.com - - [16/Oct/1997:08:20:59 -0700] "GET /amnesty/images/mombaby4.jpg HTTP/1.0" 200 6718+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:00 -0700] "GET /amnesty/images/penhand3.gif HTTP/1.0" 200 1181+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:02 -0700] "GET /amnesty/images/kids3.gif HTTP/1.0" 200 8552+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:03 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:03 -0700] "GET /amnesty/images/womland2.jpg HTTP/1.0" 200 10884+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:05 -0700] "GET /amnesty/images/cabut.gif HTTP/1.0" 200 1425+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:05 -0700] "GET /amnesty/images/candles3.jpg HTTP/1.0" 200 5240+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:06 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:07 -0700] "GET /amnesty/images/newbut.gif HTTP/1.0" 200 1357+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:08 -0700] "GET /amnesty/images/aboutbut.gif HTTP/1.0" 200 1277+user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:28 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:31 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:31 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:32 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+user-37kbnkv.dialup.mindspring.com - - [16/Oct/1997:08:21:34 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:50 -0700] "GET /amnesty/legal.html HTTP/1.0" 200 5654+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:53 -0700] "GET /amnesty/images/blkcnd2.gif HTTP/1.0" 200 1082+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:54 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:55 -0700] "GET /amnesty/images/joinbut.gif HTTP/1.0" 200 409+ww-to03.proxy.aol.com - - [16/Oct/1997:08:21:56 -0700] "GET /amnesty/images/clear1.jpg HTTP/1.0" 200 849+152.157.224.6 - - [16/Oct/1997:08:22:12 -0700] "GET /amnesty/women/fgmegypt.html HTTP/1.0" 200 6256+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:24 -0700] "GET /amnesty/casework/index.html HTTP/1.0" 200 2974+152.157.224.6 - - [16/Oct/1997:08:22:24 -0700] "GET /amnesty/images/homebut.gif HTTP/1.0" 200 518+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:26 -0700] "GET /amnesty/images/aiusarex.gif HTTP/1.0" 200 3237+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:27 -0700] "GET /amnesty/images/homebutx.gif HTTP/1.0" 200 875+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/casework/images/bothlogo.gif HTTP/1.0" 200 8650+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/newbutx.gif HTTP/1.0" 200 1714+152.157.224.6 - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/pnbut.gif HTTP/1.0" 200 670+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/pnbutx.gif HTTP/1.0" 200 1027+152.157.224.6 - - [16/Oct/1997:08:22:28 -0700] "GET /amnesty/images/womenbut.gif HTTP/1.0" 200 1367+152.157.224.6 - - [16/Oct/1997:08:22:30 -0700] "GET /amnesty/images/helpbut.gif HTTP/1.0" 200 536+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/aboutbux.gif HTTP/1.0" 200 1634+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/cabutx.gif HTTP/1.0" 200 1782+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:35 -0700] "GET /amnesty/images/joinbutx.gif HTTP/1.0" 200 766+ppp4-35.igc.org - - [16/Oct/1997:08:22:46 -0700] "GET /regions/maregcon.html HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:22:47 -0700] "GET /images/picasso.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:22:47 -0700] "GET /images/women05.jpg HTTP/1.0" 304 -+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:48 -0700] "GET /amnesty/group.html HTTP/1.0" 200 8575+ppp4-35.igc.org - - [16/Oct/1997:08:22:50 -0700] "GET /regions/maregcon.html HTTP/1.0" 304 -+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/canfuz1.gif HTTP/1.0" 200 3013+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/goldfla2.gif HTTP/1.0" 200 1161+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:52 -0700] "GET /amnesty/images/grncndl.gif HTTP/1.0" 200 1471+ppp4-35.igc.org - - [16/Oct/1997:08:22:52 -0700] "GET /images/picasso.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:22:52 -0700] "GET /images/women05.jpg HTTP/1.0" 304 -+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:56 -0700] "GET /amnesty/images/can1_2.gif HTTP/1.0" 200 30430+ww-to03.proxy.aol.com - - [16/Oct/1997:08:22:58 -0700] "GET /amnesty/images/04candle.gif HTTP/1.0" 200 7257+ww-to03.proxy.aol.com - - [16/Oct/1997:08:23:08 -0700] "GET /amnesty/images/evenbut.gif HTTP/1.0" 200 399+nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:13 -0700] "GET /comm/herbert.html HTTP/1.0" 304 -+nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:14 -0700] "GET /comm/images/dot_clea.gif HTTP/1.0" 200 43+nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:20 -0700] "GET /comm/images/bsilk7.gif HTTP/1.0" 200 10517+nyc-ny53-56.ix.netcom.com - - [16/Oct/1997:08:24:25 -0700] "GET /comm/images/people/herbert4.jpg HTTP/1.0" 200 11129+ppp4-35.igc.org - - [16/Oct/1997:08:27:11 -0700] "GET /regions/maregcon.html HTTP/1.0" 200 1304+ppp4-35.igc.org - - [16/Oct/1997:08:27:14 -0700] "GET /images/picasso.gif HTTP/1.0" 304 -+ppp4-35.igc.org - - [16/Oct/1997:08:27:14 -0700] "GET /images/women05.jpg HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:29:55 -0700] "GET /argact/ HTTP/1.0" 404 160+204.48.151.245 - - [16/Oct/1997:08:30:03 -0700] "GET /urgact/ HTTP/1.0" 200 8283+204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/homebutx.gif HTTP/1.0" 200 875+204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/newbutx.gif HTTP/1.0" 200 1714+204.48.151.245 - - [16/Oct/1997:08:30:04 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+204.48.151.245 - - [16/Oct/1997:08:30:06 -0700] "GET /images/aboutbux.gif HTTP/1.0" 200 1634+204.48.151.245 - - [16/Oct/1997:08:30:06 -0700] "GET /images/cabutx.gif HTTP/1.0" 200 1782+204.48.151.245 - - [16/Oct/1997:08:30:10 -0700] "GET /images/joinbutx.gif HTTP/1.0" 200 766+209.76.123.200 - - [16/Oct/1997:08:31:26 -0700] "GET /weeklyua.html HTTP/1.0" 200 11321+204.48.151.245 - - [16/Oct/1997:08:32:32 -0700] "GET /urgact/ HTTP/1.0" 200 -+204.48.151.245 - - [16/Oct/1997:08:32:36 -0700] "GET /images/logo2.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:37 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:37 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:38 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:38 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:39 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:32:43 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:13 -0700] "GET /home.html HTTP/1.0" 200 3854+204.48.151.245 - - [16/Oct/1997:08:33:26 -0700] "GET /index.html HTTP/1.0" 200 3082+204.48.151.245 - - [16/Oct/1997:08:33:27 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+204.48.151.245 - - [16/Oct/1997:08:33:27 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ppp37.igc.org - - [16/Oct/1997:08:33:28 -0700] "GET /casework/ HTTP/1.0" 200 2974+ppp37.igc.org - - [16/Oct/1997:08:33:29 -0700] "GET /images/aiusarex.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:30 -0700] "GET /casework/images/bothlogo.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:30 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:31 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:31 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+ppp37.igc.org - - [16/Oct/1997:08:33:32 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:33:49 -0700] "GET /joinai.html HTTP/1.0" 200 4054+204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+204.48.151.245 - - [16/Oct/1997:08:33:50 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+204.48.151.245 - - [16/Oct/1997:08:34:09 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+204.185.34.45 - - [16/Oct/1997:08:36:37 -0700] "GET /asa/china/ HTTP/1.0" 200 18000+204.185.34.45 - - [16/Oct/1997:08:36:46 -0700] "GET /asa/china/contents.html HTTP/1.0" 200 3336+204.185.34.45 - - [16/Oct/1997:08:36:49 -0700] "GET /asa/china/images/smflag.gif HTTP/1.0" 200 951+204.185.34.45 - - [16/Oct/1997:08:37:11 -0700] "GET /asa/china/chinese.html HTTP/1.0" 200 8192+204.185.34.45 - - [16/Oct/1997:08:37:21 -0700] "GET /asa/china/images/welcome.gif HTTP/1.0" 200 1049+204.185.34.45 - - [16/Oct/1997:08:37:37 -0700] "GET /asa/china/images/tibet.gif HTTP/1.0" 200 1241+204.185.34.45 - - [16/Oct/1997:08:37:38 -0700] "GET /asa/china/images/hk.gif HTTP/1.0" 200 1212+204.185.34.45 - - [16/Oct/1997:08:37:39 -0700] "GET /asa/china/images/xj.gif HTTP/1.0" 200 1247+204.185.34.45 - - [16/Oct/1997:08:37:47 -0700] "GET /asa/china/images/mail8380.gif HTTP/1.0" 200 4196+204.185.34.45 - - [16/Oct/1997:08:37:48 -0700] "GET /asa/china/images/link.gif HTTP/1.0" 200 4236+204.185.34.45 - - [16/Oct/1997:08:37:53 -0700] "GET /asa/china/images/renquan.gif HTTP/1.0" 200 411+204.185.34.45 - - [16/Oct/1997:08:38:00 -0700] "GET /asa/china/images/zhongwen.gif HTTP/1.0" 200 1202+204.185.34.45 - - [16/Oct/1997:08:38:16 -0700] "GET /asa/china/images/what-is-ai-chinese.gif HTTP/1.0" 200 3648+204.185.34.45 - - [16/Oct/1997:08:38:17 -0700] "GET /asa/china/images/ar97.jpg HTTP/1.0" 200 8192+204.185.34.45 - - [16/Oct/1997:08:38:17 -0700] "GET /asa/china/images/dzlbanner.gif HTTP/1.0" 200 16384+ppp31.igc.org - - [16/Oct/1997:08:38:50 -0700] "GET /images/homelogo.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:51 -0700] "GET /images/hometake.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:51 -0700] "GET /images/writbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:52 -0700] "GET /home.html HTTP/1.0" 200 17234+ppp31.igc.org - - [16/Oct/1997:08:38:52 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:53 -0700] "GET /images/pnbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:53 -0700] "GET /images/spanbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/candles3.jpg HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/joinbut2.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:54 -0700] "GET /images/rsacirat.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/homenew.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/homeside.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:55 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:56 -0700] "GET /images/helpbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/eventbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:57 -0700] "GET /images/pubbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:58 -0700] "GET /images/savebutx.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/countbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/getbut.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:38:59 -0700] "GET /images/membutx.gif HTTP/1.0" 304 -+ppp31.igc.org - - [16/Oct/1997:08:39:50 -0700] "GET /members/afreport.html HTTP/1.0" 401 350+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:05 -0700] "GET / HTTP/1.0" 200 3082+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:06 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:11 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ppp31.igc.org - amnesty [16/Oct/1997:08:40:11 -0700] "GET /members/afreport.html HTTP/1.0" 200 450+204.48.151.245 - - [16/Oct/1997:08:40:44 -0700] "GET /urgact/ HTTP/1.0" 200 -+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:46 -0700] "GET /images/dot.gif HTTP/1.0" 200 946+204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/homebutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/logo2.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/newbutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:40:46 -0700] "GET /images/pnbutx.gif HTTP/1.0" 304 -+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:46 -0700] "GET /images/refbut.gif HTTP/1.0" 200 1182+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:47 -0700] "GET /aicapn2.html HTTP/1.0" 200 12769+204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:40:48 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/campbut.gif HTTP/1.0" 200 1257+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/deathbut.gif HTTP/1.0" 200 1310+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:50 -0700] "GET /images/pandnlog.gif HTTP/1.0" 200 15944+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:51 -0700] "GET /images/groupbut.gif HTTP/1.0" 200 1173+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:51 -0700] "GET /images/lgbut.gif HTTP/1.0" 200 614+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:52 -0700] "GET /images/ncasebut.gif HTTP/1.0" 200 1427+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:52 -0700] "GET /images/uabut.gif HTTP/1.0" 200 1288+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:53 -0700] "GET /images/legalbut.gif HTTP/1.0" 200 1097+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/educbut.gif HTTP/1.0" 200 1246+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/ganbut.gif HTTP/1.0" 200 1414+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/healbut.gif HTTP/1.0" 200 1492+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:54 -0700] "GET /images/womenbut.gif HTTP/1.0" 200 1367+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:55 -0700] "GET /images/wordo35d.gif HTTP/1.0" 200 7089+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/candles3.jpg HTTP/1.0" 200 5240+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/mombaby4.jpg HTTP/1.0" 200 6718+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:56 -0700] "GET /images/penhand3.gif HTTP/1.0" 200 1181+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:40:59 -0700] "GET /images/womland2.jpg HTTP/1.0" 200 10884+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:00 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:02 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:03 -0700] "GET /images/helpbut.gif HTTP/1.0" 200 536+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:05 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:05 -0700] "GET /images/kids3.gif HTTP/1.0" 200 8552+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:09 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+204.48.151.245 - - [16/Oct/1997:08:41:21 -0700] "GET /images/aboutbux.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:41:21 -0700] "GET /images/cabutx.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:41:22 -0700] "GET /images/joinbutx.gif HTTP/1.0" 304 -+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:37 -0700] "GET /images/ai_emb2.gif HTTP/1.0" 200 2189+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:37 -0700] "GET /tools/dot_clea.gif HTTP/1.0" 200 43+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:39 -0700] "GET /ainews.html HTTP/1.0" 200 13435+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:39 -0700] "GET /spanish/images/spespbut.gif HTTP/1.0" 200 427+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:41 -0700] "GET /images/refhand4.gif HTTP/1.0" 200 6789+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:44 -0700] "GET /images/newslogo.gif HTTP/1.0" 200 17448+204.48.151.245 - - [16/Oct/1997:08:41:45 -0700] "GET /urgact/contact.html HTTP/1.0" 200 882+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:52 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:52 -0700] "GET /images/pubbut.gif HTTP/1.0" 200 1291+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:53 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:53 -0700] "GET /images/joinbut.gif HTTP/1.0" 200 409+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:41:58 -0700] "GET /images/countbut.gif HTTP/1.0" 200 1673+204.48.151.245 - - [16/Oct/1997:08:42:04 -0700] "GET /index.html HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:06 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+204.48.151.245 - - [16/Oct/1997:08:42:15 -0700] "GET /joinai.html HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:18 -0700] "GET /images/aboutbut.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:18 -0700] "GET /images/homebut.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:20 -0700] "GET /images/cabut.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:23 -0700] "GET /images/amnesty.gif HTTP/1.0" 304 -+204.48.151.245 - - [16/Oct/1997:08:42:24 -0700] "GET /images/newbut.gif HTTP/1.0" 304 -+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:37 -0700] "GET /candatop.html HTTP/1.0" 200 10629+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:38 -0700] "GET /images/done.gif HTTP/1.0" 200 4785+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:40 -0700] "GET /images/candalog.gif HTTP/1.0" 200 8638+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:41 -0700] "GET /images/reyes.gif HTTP/1.0" 200 10859+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:42 -0700] "GET /images/reddash2.gif HTTP/1.0" 200 237+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:43 -0700] "GET /images/rally4.jpg HTTP/1.0" 200 7352+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:44 -0700] "GET /images/hasene2.gif HTTP/1.0" 200 8833+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:44 -0700] "GET /images/kids5.jpg HTTP/1.0" 200 2903+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:45 -0700] "GET /images/refrun1.gif HTTP/1.0" 200 836+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:46 -0700] "GET /images/nigpost1.gif HTTP/1.0" 200 4429+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:46 -0700] "GET /images/turkboy.gif HTTP/1.0" 200 4625+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:48 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:43:51 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:33 -0700] "GET /images/linebrn.gif HTTP/1.0" 200 308+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:33 -0700] "GET /images/logo2.gif HTTP/1.0" 200 6343+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:44:37 -0700] "GET /weeklyua.html HTTP/1.0" 200 11321+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:00 -0700] "GET /about.html HTTP/1.0" 200 6902+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:01 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:01 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:03 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:45:07 -0700] "GET /images/where.gif HTTP/1.0" 200 605+ppp48.centraltx.net - - [16/Oct/1997:08:49:35 -0700] "GET / HTTP/1.0" 200 3082+ppp48.centraltx.net - - [16/Oct/1997:08:49:38 -0700] "GET /images/bsilk7.gif HTTP/1.0" 404 170+ppp48.centraltx.net - - [16/Oct/1997:08:49:47 -0700] "GET /images/spot5.gif HTTP/1.0" 200 9372+ppp48.centraltx.net - - [16/Oct/1997:08:49:53 -0700] "GET /joinai.html HTTP/1.0" 200 4054+ppp48.centraltx.net - - [16/Oct/1997:08:49:55 -0700] "GET /images/amnesty.gif HTTP/1.0" 200 1158+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /about/history.html HTTP/1.0" 200 10342+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /images/aiusared.gif HTTP/1.0" 200 2725+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:56 -0700] "GET /images/blkcnd2.gif HTTP/1.0" 200 1082+ppp48.centraltx.net - - [16/Oct/1997:08:49:58 -0700] "GET /images/homebut.gif HTTP/1.0" 200 518+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/airmail2.jpg HTTP/1.0" 200 7820+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/backtono.gif HTTP/1.0" 200 2367+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:49:59 -0700] "GET /about/images/sagan4.gif HTTP/1.0" 200 3596+ppp48.centraltx.net - - [16/Oct/1997:08:49:59 -0700] "GET /images/aboutbut.gif HTTP/1.0" 200 1277+ppp48.centraltx.net - - [16/Oct/1997:08:49:59 -0700] "GET /images/pnbutx.gif HTTP/1.0" 200 1027+ppp48.centraltx.net - - [16/Oct/1997:08:50:00 -0700] "GET /images/cabut.gif HTTP/1.0" 200 1425+ppp48.centraltx.net - - [16/Oct/1997:08:50:00 -0700] "GET /images/newbut.gif HTTP/1.0" 200 1357+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:01 -0700] "GET /images/wamwer6.jpg HTTP/1.0" 200 9786+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:04 -0700] "GET /about/images/coverbut.gif HTTP/1.0" 200 400+shadow-01.sturgeon.ab.ca - - [16/Oct/1997:08:50:07 -0700] "GET /about/images/masthd3.gif HTTP/1.0" 200 33250+ppp48.centraltx.net - - [16/Oct/1997:08:50:09 -0700] "GET /images/spot5.gif HTTP/1.0" 200 3855+ppp48.centraltx.net - - [16/Oct/1997:08:50:15 -0700] "GET /about.html HTTP/1.0" 200 6902+ppp48.centraltx.net - - [16/Oct/1997:08:50:19 -0700] "GET /images/howbut.gif HTTP/1.0" 200 509+ppp48.centraltx.net - - [16/Oct/1997:08:50:20 -0700] "GET /images/whobut.gif HTTP/1.0" 200 505+ppp48.centraltx.net - - [16/Oct/1997:08:50:22 -0700] "GET /images/netbut.gif HTTP/1.0" 200 1191+ppp48.centraltx.net - - [16/Oct/1997:08:50:24 -0700] "GET /images/whatbut.gif HTTP/1.0" 200 526+ppp48.centraltx.net - - [16/Oct/1997:08:50:25 -0700] "GET /images/eventbut.gif HTTP/1.0" 200 380+ppp48.centraltx.net - - [16/Oct/1997:08:50:27 -0700] "GET /images/aalogo.gif HTTP/1.0" 200 15293+ecarh29c.nortel.ca - - [16/Oct/1997:08:50:34 -0700] "GET /country/balkans HTTP/1.0" 301 196+ecarh29c.nortel.ca - - [16/Oct/1997:08:50:35 -0700] "GET /country/balkans/ HTTP/1.0" 200 2778+ecarh29c.nortel.ca - - [16/Oct/1997:08:50:38 -0700] "GET /country/balkans/images/dot.gif HTTP/1.0" 200 46+ecarh29c.nortel.ca - - [16/Oct/1997:08:50:38 -0700] "GET /country/balkans/images/head.gif HTTP/1.0" 200 2908+ppp48.centraltx.net - - [16/Oct/1997:08:50:40 -0700] "GET /quiz.html HTTP/1.0" 200 10126+ecarh29c.nortel.ca - - [16/Oct/1997:08:50:41 -0700] "GET /country/balkans/images/bosnia.gif HTTP/1.0" 200 638+ppp48.centraltx.net - - [16/Oct/1997:08:50:42 -0700] "GET /images/dot_clea.gif HTTP/1.0" 200 43
file too large to diff
@@ -0,0 +1,1 @@+25 23 300 -400 899 9876 -98744 97687676543 -98765432187
binary file changed (absent → 32 bytes)
@@ -0,0 +1,1 @@+ª»ÌÝccdd
@@ -0,0 +1,11 @@+221 2360199 936 3615299 96977709 71+221 2360399 855 5445599 96978527 126+221 2390199 974 4298199 96980122 990+221 2390399 855 5404599 96976885 35+222 2332099 426 6814599 96977173 4850+222 2332099 -15 9999999 96978457 533+222 2340599 855 8442799 96980047 8+222 2341299 855 7081599 96979104 11+223 2340099 855 2484499 96977739 564+223 2340199 -15 9999999 96979345 143+
binary file changed (absent → 240 bytes)
@@ -0,0 +1,40 @@+#include <stdio.h>++/* Reads ascii call detail records from stdin.+ * Writes scampRec binary call detail records on stdout.+ */++typedef struct+{+ unsigned char uc;+ signed char sc;+ unsigned short us;+ signed short ss;+ signed short ss2;+ unsigned int ui;+ signed int si;+ unsigned long long ull;+ signed long long sll;+} binRec_t;++++int readAscii(FILE *in, binRec_t *r){+ int success = fscanf(in, "%hhu %hhd %hu %hd %hd %u %d %llu %lld\n",+ &(r->uc), &(r->sc), + &(r->us), &(r->ss), &(r->ss2),+ &(r->ui), &(r->si),+ &(r->ull),&(r->sll)); + return success;+}++void writeBinary(FILE *out, binRec_t *r){+ fwrite(r, sizeof(binRec_t), 1, out);+}++int main(){+ binRec_t current;+ while (readAscii(stdin, ¤t) != EOF)+ writeBinary(stdout, ¤t);+ return 0;+}
@@ -0,0 +1,33 @@+00400000-00422000 r-xp 00000000 fe:02 4968 /usr/bin/less+00622000-00623000 r--p 00022000 fe:02 4968 /usr/bin/less+00623000-00627000 rw-p 00023000 fe:02 4968 /usr/bin/less+00627000-0062b000 rw-p 00000000 00:00 0 +00aa0000-00ac1000 rw-p 00000000 00:00 0 [heap]+7f1ae9999000-7f1ae99b2000 r-xp 00000000 fe:02 93235 /usr/lib/libpthread-2.25.so+7f1ae99b2000-7f1ae9bb1000 ---p 00019000 fe:02 93235 /usr/lib/libpthread-2.25.so+7f1ae9bb1000-7f1ae9bb2000 r--p 00018000 fe:02 93235 /usr/lib/libpthread-2.25.so+7f1ae9bb2000-7f1ae9bb3000 rw-p 00019000 fe:02 93235 /usr/lib/libpthread-2.25.so+7f1ae9bb3000-7f1ae9bb7000 rw-p 00000000 00:00 0 +7f1ae9bb7000-7f1ae9d52000 r-xp 00000000 fe:02 93077 /usr/lib/libc-2.25.so+7f1ae9d52000-7f1ae9f51000 ---p 0019b000 fe:02 93077 /usr/lib/libc-2.25.so+7f1ae9f51000-7f1ae9f55000 r--p 0019a000 fe:02 93077 /usr/lib/libc-2.25.so+7f1ae9f55000-7f1ae9f57000 rw-p 0019e000 fe:02 93077 /usr/lib/libc-2.25.so+7f1ae9f57000-7f1ae9f5b000 rw-p 00000000 00:00 0 +7f1ae9f5b000-7f1ae9fcd000 r-xp 00000000 fe:02 108084 /usr/lib/libpcre.so.1.2.8+7f1ae9fcd000-7f1aea1cc000 ---p 00072000 fe:02 108084 /usr/lib/libpcre.so.1.2.8+7f1aea1cc000-7f1aea1cd000 r--p 00071000 fe:02 108084 /usr/lib/libpcre.so.1.2.8+7f1aea1cd000-7f1aea1ce000 rw-p 00072000 fe:02 108084 /usr/lib/libpcre.so.1.2.8+7f1aea1ce000-7f1aea235000 r-xp 00000000 fe:02 106343 /usr/lib/libncursesw.so.6.0+7f1aea235000-7f1aea434000 ---p 00067000 fe:02 106343 /usr/lib/libncursesw.so.6.0+7f1aea434000-7f1aea438000 r--p 00066000 fe:02 106343 /usr/lib/libncursesw.so.6.0+7f1aea438000-7f1aea43a000 rw-p 0006a000 fe:02 106343 /usr/lib/libncursesw.so.6.0+7f1aea43a000-7f1aea45d000 r-xp 00000000 fe:02 93078 /usr/lib/ld-2.25.so+7f1aea490000-7f1aea629000 r--p 00000000 fe:02 96759 /usr/lib/locale/locale-archive+7f1aea629000-7f1aea62d000 rw-p 00000000 00:00 0 +7f1aea65c000-7f1aea65d000 r--p 00022000 fe:02 93078 /usr/lib/ld-2.25.so+7f1aea65d000-7f1aea65e000 rw-p 00023000 fe:02 93078 /usr/lib/ld-2.25.so+7f1aea65e000-7f1aea65f000 rw-p 00000000 00:00 0 +7fff3cc14000-7fff3cc35000 rw-p 00000000 00:00 0 [stack]+7fff3cc3a000-7fff3cc3c000 r--p 00000000 00:00 0 [vvar]+7fff3cc3c000-7fff3cc3e000 r-xp 00000000 00:00 0 [vdso]+ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
@@ -0,0 +1,3 @@+8,Hermione+3,Ron+5,Harry
@@ -0,0 +1,991 @@+{-# LANGUAGE DeriveDataTypeable+ , DeriveGeneric+ , DeriveLift+ , FlexibleContexts+ , FlexibleInstances+ , MultiParamTypeClasses+ , QuasiQuotes+ , ScopedTypeVariables+ , TemplateHaskell+ , TypeFamilies+ , TypeSynonymInstances+ , UndecidableInstances #-}++module Main where++import Data.Bits+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as BC+import Data.Char (isDigit)+import Data.Maybe (fromJust)+import Data.Time.Clock.POSIX (getPOSIXTime)+import Data.Word++import Control.Monad+import Control.Monad.State as ST+import Numeric (showHex, readHex)+import Language.Haskell.TH+import Language.Haskell.TH.Syntax+import System.IO.Unsafe (unsafePerformIO)+import Test.HUnit hiding (test)++import Language.Pads.Padsc+import qualified Language.Pads.Library.LittleEndian as LE+import qualified Language.Pads.Library.BigEndian as BE++-- Some tests in this suite compare "expected" and "got" as lists of Chunks,+-- and some as ByteStrings. Often, if the comparison is between lists of+-- Chunks, it's because doing so makes the test more readable/understable,+-- often because it includes bit-level data which is easier to view as Chunks.+-- The difference in these two types of tests is a call to @fromChunks@ and+-- usually a call to @pack@. The standalone testing of @fromChunks@, as+-- well as those more complex tests that include it, should be sufficient to+-- ensure its correctness.++sampleSize = 100 -- used for "cycle" testing - generate, serialize, parse++--------------------------------------------------------------------------------+-- Unit testing of serialization of pure/primitive PADS types++charTest_name = "Char"+charTest_expected = BC.pack "a"+charTest_got = fromChunks $ fromCL $ char_serialize 'a'+charTest = TestCase (charTest_expected @=? charTest_got)++charCycleTest_name = "Char Cycle"+charCycleTest = do+ cs <- replicateM sampleSize (runPadsGen char_genM)+ let cs_serialized = map (BC.unpack . fromChunks . fromCL . char_serialize) cs+ let cs_parsed = map (fst . fst . (parseStringInput char_parseM)) cs_serialized+ return $ cs == cs_parsed++intTest_name = "Int"+intTest_expected = BC.pack "12"+intTest_got = fromChunks $ fromCL $ int_serialize 12+intTest = TestCase (intTest_expected @=? intTest_got)++intCycleTest_name = "Int Cycle"+intCycleTest = do+ xs <- replicateM sampleSize (runPadsGen int_genM)+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . int_serialize) xs+ let xs_parsed = map (fst . fst . (parseStringInput int_parseM)) xs_serialized+ return $ xs == xs_parsed++-- Purely for parsers that ignore default newline record discipline+[pads| type Bits8N = partition Bits8 8 using none+ type Bits16N = partition Bits16 16 using none+ type Bits32N = partition Bits32 32 using none+ type Bits64N = partition Bits64 64 using none+ type BitBoolN = partition BitBool using none |]+bits8Test_name = "Bits8"+bits8Test_expected = B.pack [98]+bits8Test_got = (fromChunks $ (fromCL $ ((bits8_serialize 8) 98)))+bits8Test = TestCase (bits8Test_expected @=? bits8Test_got)++bits8CycleTest_name = "Bits8 Cycle"+bits8CycleTest = do+ xs <- replicateM sampleSize (runPadsGen (bits8_genM 8))+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . (bits8_serialize 8)) xs+ let xs_parsed = map (fst . fst . (parseStringInput bits8N_parseM)) xs_serialized+ return $ xs == xs_parsed++bits8MisalignedTest_name = "Bits8 Misaligned"+bits8MisalignedTest_expected = B.pack [224] -- representing 11100000 (or 7 << 5)+bits8MisalignedTest_got+ = (fromChunks $ (fromCL $ ((bits8_serialize 3) 7)))+bits8MisalignedTest+ = TestCase+ (bits8MisalignedTest_expected @=? bits8MisalignedTest_got)++bits16Test_name = "Bits16"+bits16Test_expected = B.pack [139,74]+bits16Test_got = (fromChunks $ (fromCL $ ((bits16_serialize 16) 35658)))+bits16Test = TestCase (bits16Test_expected @=? bits16Test_got)++bits16CycleTest_name = "Bits16 Cycle"+bits16CycleTest = do+ xs <- replicateM sampleSize (runPadsGen (bits16_genM 16))+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . (bits16_serialize 16)) xs+ let xs_parsed = map (fst . fst . (parseStringInput bits16N_parseM)) xs_serialized+ return $ xs == xs_parsed++bits16MisalignedTest_name = "Bits16 Misaligned"+bits16MisalignedTest_expected = B.pack [224,192] -- representing 1110000011000000 (or 899 << 6)+bits16MisalignedTest_got+ = (fromChunks $ (fromCL $ ((bits16_serialize 10) 899)))+bits16MisalignedTest+ = TestCase+ (bits16MisalignedTest_expected @=? bits16MisalignedTest_got)++bits32Test_name = "Bits32"+bits32Test_expected = B.pack [128,128,128,129]+bits32Test_got = (fromChunks $ (fromCL $ ((bits32_serialize 32) 2155905153)))+bits32Test = TestCase (bits32Test_expected @=? bits32Test_got)++bits32CycleTest_name = "Bits32 Cycle"+bits32CycleTest = do+ xs <- replicateM sampleSize (runPadsGen (bits32_genM 32))+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . (bits32_serialize 32)) xs+ let xs_parsed = map (fst . fst . (parseStringInput bits32N_parseM)) xs_serialized+ return $ xs == xs_parsed++bits64Test_name = "Bits64"+bits64Test_expected = B.pack [128,128,128,128,128,128,128,129]+bits64Test_got = (fromChunks $ (fromCL $ ((bits64_serialize 64) 9259542123273814145)))+bits64Test = TestCase (bits64Test_expected @=? bits64Test_got)++bits64CycleTest_name = "Bits64 Cycle"+bits64CycleTest = do+ xs <- replicateM sampleSize (runPadsGen (bits64_genM 64))+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . (bits64_serialize 64)) xs+ let xs_parsed = map (fst . fst . (parseStringInput bits64N_parseM)) xs_serialized+ return $ xs == xs_parsed++bitBoolTest_name = "BitBool"+bitBoolTest_expected = B.pack [128]+bitBoolTest_got = (fromChunks . fromCL . bitBool_serialize) True+bitBoolTest = TestCase (bitBoolTest_expected @=? bitBoolTest_got)++bitBoolCycleTest_name = "BitBool Cycle"+bitBoolCycleTest = do+ bs <- replicateM sampleSize (runPadsGen bitBool_genM)+ let bs_serialized = map (BC.unpack . fromChunks . fromCL . bitBool_serialize) bs+ let bs_parsed = map (fst . fst . (parseStringInput bitBoolN_parseM)) bs_serialized+ return $ bs == bs_parsed++-- | Use BitField generator and serializer but BitField50 parser to avoid record+-- discipline problems+[pads| type BitField50 = partition BitField 50 using none |]+bitFieldCycleTest_name = "BitField Cycle"+bitFieldCycleTest = do+ xs <- replicateM sampleSize (runPadsGen (bitField_genM 50))+ let xs_serialized = map (BC.unpack . fromChunks . fromCL . (bitField_serialize 50)) xs+ let xs_parsed = map (fst . fst . bitField50_parseS) xs_serialized+ return $ xs == xs_parsed++bytesTest_name = "Bytes"+bytesTest_expected = B.pack [1, 2, 3, 4]+bytesTest_got+ = (fromChunks $ (fromCL $ ((bytes_serialize 4) $ (B.pack [1, 2, 3, 4]))))+bytesTest = TestCase (bytesTest_expected @=? bytesTest_got)++[pads| type MyStringC = StringC 'f' |]++myStringCTest_name = "MyStringC"+myStringCTest_expected = BC.pack "tgif"+myStringCTest_got = fromChunks (fromCL $ (myStringC_serialize "tgi"))+myStringCTest+ = TestCase (myStringCTest_expected @=? myStringCTest_got)++myStringCCycleTest_name = "MyStringC Cycle"+myStringCCycleTest = do+ ss <- replicateM sampleSize (runPadsGen myStringC_genM)+ let ss_serialized = map (BC.unpack . fromChunks . fromCL . myStringC_serialize) ss+ let ss_parsed = map (fst . fst . myStringC_parseS) ss_serialized+ return $ ss == ss_parsed++-------------------------------------------------------------------------------+-- Unit testing of user-defined PADS types++-- Simple tuple with literals+[pads| type MyTuple = (Int,'c',Bits8 4,'d') |]++myTupleTest_name = "MyTuple"+myTupleTest_expected+ = [CharChunk '1', CharChunk 'c', (BinaryChunk 10) 4, CharChunk 'd']+myTupleTest_got = fromCL $ myTuple_serialize (1, 10)+myTupleTest+ = TestCase (myTupleTest_expected @=? myTupleTest_got)++myTupleCycleTest_name = "MyTuple Cycle"+myTupleCycleTest = do+ ts <- replicateM sampleSize (runPadsGen myTuple_genM)+ let ts_serialized = map (BC.unpack . fromChunks . fromCL . myTuple_serialize) ts+ let ts_parsed = map (fst . fst . myTuple_parseS) ts_serialized+ return $ ts == ts_parsed++-- Application of type to argument+[pads| type Byte = Bits8 8+ type ByteN = partition Byte using none |]++byteTest_name = "Byte"+byteTest_expected = [(BinaryChunk 254) 8]+byteTest_got = fromCL $ byte_serialize 254+byteTest = TestCase (byteTest_expected @=? byteTest_got)++byteCycleTest_name = "Byte Cycle"+byteCycleTest = do+ bs <- replicateM sampleSize (runPadsGen byte_genM)+ let bs_serialized = map (BC.unpack . fromChunks . fromCL . byte_serialize) bs+ let bs_parsed = map (fst . fst . byteN_parseS) bs_serialized+ return $ bs == bs_parsed++-- PPartition (generation) with reference to previously defined type+[pads| type TwoBytes = (Byte, Byte)+ type TwoBytesP = partition TwoBytes using none |]++twoBytesTest_name = "TwoBytes"+twoBytesTest_expected = [(BinaryChunk 0) 8, (BinaryChunk 122) 8]+twoBytesTest_got = fromCL $ twoBytes_serialize (0, 122)+twoBytesTest+ = TestCase (twoBytesTest_expected @=? twoBytesTest_got)++twoBytesCycleTest_name = "TwoBytes Cycle"+twoBytesCycleTest = do+ ts <- replicateM sampleSize (runPadsGen twoBytesP_genM)+ let ts_serialized = map (BC.unpack . fromChunks . fromCL . twoBytes_serialize) ts+ let ts_parsed = map (fst . fst . twoBytesP_parseS) ts_serialized+ return $ ts == ts_parsed++-- Nested tuple+[pads| type TupleN = (Int, ',', (Int,':',Int), ';', Int) |]+nestedTupleTest_name = "Nested Tuple"+nestedTupleTest_expected = BC.pack "1,2:3;4"+nestedTupleTest_got = fromChunks $ fromCL $ tupleN_serialize (1, (2, 3), 4)+nestedTupleTest+ = TestCase (nestedTupleTest_expected @=? nestedTupleTest_got)++-- PConstrain serialization (simple) and generation (less simple)+[pads| type CString = constrain s :: StringFW 10 where <| take 2 s == "cc" |> |]+constrainedStringTest_name = "Constrained String"+constrainedStringTest_expected = BC.pack "cc"+constrainedStringTest_got+ = (B.take 2 $ fromChunks (fromCL $ (cString_serialize "ccjqnbfkwh")))+constrainedStringTest+ = TestCase+ (constrainedStringTest_expected @=? constrainedStringTest_got)++constrainedGenTest_name = "Constrained Generation"+constrainedGenTest = do+ ss <- replicateM 3 (runPadsGen cString_genM)+ return $ all (== "cc") (map (take 2) ss)++[pads| type SimpleC = constrain s :: Int where <| s == 5 |>+ type SimpleC2 = constrain s :: Int where <| 5 == s |> |]+simpleConstraintTest_name = "Simple Constraint"+simpleConstraintTest = do+ ss <- replicateM sampleSize (runPadsGen simpleC_genM)+ return $ all (== 5) ss++simpleConstraintTest2_name = "Simple Constraint 2"+simpleConstraintTest2 = do+ ss <- replicateM sampleSize (runPadsGen simpleC2_genM)+ return $ all (== 5) ss+++-- PLists of several forms+[pads| type RegularList = [Bits8 8] |]++regularListTest_name = "RegularList"+regularListTest_expected = [(BinaryChunk 10) 8, (BinaryChunk 5) 8]+regularListTest_got+ = fromCL $ regularList_serialize [10, 5]+regularListTest+ = TestCase (regularListTest_expected @=? regularListTest_got)++[pads| type SepList = [Bits8 8 | '|'] |]+sepListTest_name = "SepList"+sepListTest_expected+ = [(BinaryChunk 10) 8, CharChunk '|', (BinaryChunk 5) 8]+sepListTest_got = fromCL $ sepList_serialize [10, 5]+sepListTest+ = TestCase (sepListTest_expected @=? sepListTest_got)++[pads| type SepTermList = [Bits8 8 | '|'] terminator Char |]+sepTermListTest_name = "SepList w/ Type Terminator"+sepTermListTest_expected+ = [(BinaryChunk 10) 8, CharChunk '|', (BinaryChunk 5) 8, CharChunk 'X']+sepTermListTest_got+ = fromCL $ sepTermList_serialize [10, 5]+sepTermListTest+ = TestCase (sepTermListTest_expected @=? sepTermListTest_got)++sepTermListBytesTest_name = "SepList w/ Type Terminator (Bytes)"+sepTermListBytesTest_expected = B.pack [10, 124, 5, 88]+sepTermListBytesTest_got = fromChunks sepTermListTest_got+sepTermListBytesTest+ = TestCase (sepTermListBytesTest_expected @=? sepTermListBytesTest_got)++[pads| type SepTermListLit = [Char | '|'] terminator '~' |]+sepTermListLitTest_name = "SepList w/ Literal Terminator"+sepTermListLitTest_expected+ = BC.pack "a|b~"+sepTermListLitTest_got+ = fromChunks $ fromCL $ sepTermListLit_serialize "ab"+sepTermListLitTest+ = TestCase (sepTermListLitTest_expected @=? sepTermListLitTest_got)++sepTermListLitCycleTest_name = "SepList w/ Literal Terminator Cycle"+sepTermListLitCycleTest = do+ ls <- replicateM sampleSize (runPadsGen sepTermListLit_genM)+ let ls_serialized = map (BC.unpack . fromChunks . fromCL . sepTermListLit_serialize) ls+ let ls_parsed = map (fst . fst . sepTermListLit_parseS) ls_serialized+ return $ ls == ls_parsed++[pads| type LenList = [Digit] length 5 |]+lenListTest_name = "List w/ Length"+lenListTest_expected+ = BC.pack "65535"+lenListTest_got+ = fromChunks $ fromCL $ lenList_serialize [6, 5, 5, 3, 5, 0, 0, 0]+lenListTest+ = TestCase (lenListTest_expected @=? lenListTest_got)++lenListCycleTest_name = "List w/ Length Cycle"+lenListCycleTest = do+ ls <- replicateM sampleSize (runPadsGen lenList_genM)+ let ls_serialized = map (BC.unpack . fromChunks . fromCL . lenList_serialize) ls+ let ls_parsed = map (fst . fst . lenList_parseS) ls_serialized+ return $ ls == ls_parsed++[pads| type SepLenList = [Digit | '|'] length 5 |]+sepLenListTest_name = "SepList w/ Length"+sepLenListTest_expected+ = BC.pack "6|5|5|3|5"+sepLenListTest_got+ = fromChunks $ fromCL $ sepLenList_serialize [6, 5, 5, 3, 5, 0, 0, 0]+sepLenListTest+ = TestCase (sepLenListTest_expected @=? sepLenListTest_got)++sepLenListCycleTest_name = "SepList w/ Length Cycle"+sepLenListCycleTest = do+ ls <- replicateM sampleSize (runPadsGen sepLenList_genM)+ let ls_serialized = map (BC.unpack . fromChunks . fromCL . sepLenList_serialize) ls+ let ls_parsed = map (fst . fst . sepLenList_parseS) ls_serialized+ return $ ls == ls_parsed+++-- Run-of-the-mill record with sub-byte data+[pads| data Pixel = Pixel { a :: Bits16 9+ , b :: Bits8 5+ , c :: Bits8 5+ , d :: Bits8 5+ , pb_index :: Bits8 4+ , pr_index :: Bits8 4 }++ type PixelNone = partition Pixel using none+ type Pixels = partition (Pixel, [Pixel]) using none |]++pixelTest_name = "Pixel"+pixelTest_expected+ = [(BinaryChunk 511) 9, (BinaryChunk 0) 5, (BinaryChunk 8) 5,+ (BinaryChunk 0) 5, (BinaryChunk 1) 4, (BinaryChunk 1) 4]+pixelTest_got = fromCL $ pixel_serialize ((((((Pixel 511) 0) 8) 0) 1) 1)+pixelTest+ = TestCase (pixelTest_expected @=? pixelTest_got)++pixelBytesTest_name = "Pixel Bytes"+pixelBytesTest_expected = B.pack [255, 129, 0, 17]+pixelBytesTest_got = fromChunks pixelTest_got+pixelBytesTest+ = TestCase (pixelBytesTest_expected @=? pixelBytesTest_got)++pixelCycleTest_name = "Pixel Cycle"+pixelCycleTest = do+ ps <- replicateM sampleSize (runPadsGen pixel_genM)+ let ps_serialized = map (BC.unpack . fromChunks . fromCL . pixel_serialize) ps+ let ps_parsed = map (fst . fst . pixelNone_parseS) ps_serialized+ return $ ps == ps_parsed++-- Constants in records+[pads| data Constants = Constants { var1 :: Int+ , "string"+ , 'c'+ , var2 :: StringFW 10 } |]++recordConstantsTest_name = "Record Constants"+recordConstantsTest_expected = BC.pack "42stringchellothere"+recordConstantsTest_got+ = (fromChunks+ $ (fromCL $ (constants_serialize $ ((Constants 42) "hellothere"))))+recordConstantsTest+ = TestCase+ (recordConstantsTest_expected @=? recordConstantsTest_got)++constantsCycleTest_name = "Constants Cycle"+constantsCycleTest = do+ cs <- replicateM sampleSize (runPadsGen constants_genM)+ let cs_serialized = map (BC.unpack . fromChunks . fromCL . constants_serialize) cs+ let cs_parsed = map (fst . fst . constants_parseS) cs_serialized+ return $ cs == cs_parsed++-- Simple PValue example+[pads| data Foo = Foo { x :: Int, xSucc = value <| x + 1 |> :: Int }+ | Bar { x :: Int } |]++fooFooTest_name = "FooFoo"+fooFooTest_expected = BC.pack "1"+fooFooTest_got = fromChunks $ fromCL $ foo_serialize ((Foo 1) 2)+fooFooTest = TestCase (fooFooTest_expected @=? fooFooTest_got)++fooBarTest_name = "FooBar"+fooBarTest_expected = BC.pack "0"+fooBarTest_got = fromChunks $ fromCL $ foo_serialize (Bar 0)+fooBarTest = TestCase (fooBarTest_expected @=? fooBarTest_got)++-- Test branch constructors+[pads| data MyConstr a = MyConstr1 Int Char+ | MyConstr2 Void+ | MyConstr3 a "Hello"+ | MyConstr4 |]++myConstr1WithArgsTest_name = "MyConstr1 (With Args)"+myConstr1WithArgsTest_expected = BC.pack "12x"+myConstr1WithArgsTest_got+ = fromChunks (fromCL $ (myConstr_serialize undefined ((MyConstr1 12) 'x')))+myConstr1WithArgsTest+ = TestCase (myConstr1WithArgsTest_expected @=? myConstr1WithArgsTest_got)++myConstr2NoArgsTest_name = "MyConstr2 (No Args)"+myConstr2NoArgsTest_expected = []+myConstr2NoArgsTest_got+ = (fromCL $ (myConstr_serialize undefined MyConstr2))+myConstr2NoArgsTest+ = TestCase (myConstr2NoArgsTest_expected @=? myConstr2NoArgsTest_got)++myConstr3TVArgsTest_name = "MyConstr3 (With Tyvar Args)"+myConstr3TVArgsTest_expected = BC.pack "3Hello"+myConstr3TVArgsTest_got+ = fromChunks (fromCL $ (myConstr_serialize int_serialize (MyConstr3 3)))+myConstr3TVArgsTest+ = TestCase+ (myConstr3TVArgsTest_expected @=? myConstr3TVArgsTest_got)++-- Odd, but this corresponds with the parser's behavior+myConstr4NoArgsTest_name = "MyConstr4 (No Args)"+myConstr4NoArgsTest_expected = BC.pack "MyConstr4"+myConstr4NoArgsTest_got+ = fromChunks (fromCL $ (myConstr_serialize undefined (MyConstr4)))+myConstr4NoArgsTest+ = TestCase (myConstr4NoArgsTest_expected @=? myConstr4NoArgsTest_got)++-- NB: This test fails on account of odd parsing behavior - it's included here+-- as an example but excluded from the actual list of tests+myConstrCycleTest_name = "MyConstr Cycle"+myConstrCycleTest = do+ cs <- replicateM sampleSize (runPadsGen (myConstr_genM int_genM))+ let cs_serialized = map (BC.unpack . fromChunks . fromCL . (myConstr_serialize int_serialize)) cs+ let cs_parsed = map (fst . fst . (myConstr_parseS int_parseM)) cs_serialized+ return $ cs == cs_parsed++-- Test use of type variables+[pads| data MyList a = MyCons a (MyList a)+ | MyNil Void |]++myListEmptyTest_name = "MyList Empty"+myListEmptyTest_expected = []+myListEmptyTest_got+ = (fromCL $ ((myList_serialize undefined) MyNil))+myListEmptyTest+ = TestCase (myListEmptyTest_expected @=? myListEmptyTest_got)++myListNonemptyTest_name = "MyList Nonempty"+myListNonemptyTest_expected = BC.pack "foo"+myListNonemptyTest_got+ = fromChunks+ (fromCL+ $ ((myList_serialize char_serialize)+ ((MyCons 'f') ((MyCons 'o') ((MyCons 'o') MyNil)))))+myListNonemptyTest+ = TestCase (myListNonemptyTest_expected @=? myListNonemptyTest_got)++myListCycleTest_name = "MyList Cycle"+myListCycleTest = do+ ls <- replicateM sampleSize (runPadsGen (myList_genM char_genM))+ let ls_serialized = map (BC.unpack . fromChunks . fromCL . (myList_serialize char_serialize)) ls+ let ls_parsed = map (fst . fst . (myList_parseS char_parseM)) ls_serialized+ return $ ls == ls_parsed++[pads| newtype NT = NT Int |]++nTTest_name = "NewType"+nTTest_expected = BC.pack "3"+nTTest_got = fromChunks (fromCL $ (nT_serialize (NT 3)))+nTTest = TestCase (nTTest_expected @=? nTTest_got)++nTCycleTest_name = "NewType Cycle"+nTCycleTest = do+ nts <- replicateM sampleSize (runPadsGen nT_genM)+ let nts_serialized = map (BC.unpack . fromChunks . fromCL . nT_serialize) nts+ let nts_parsed = map (fst . fst . nT_parseS) nts_serialized+ return $ nts == nts_parsed++-- PSwitch - should desugar to simple record+[pads| data SwitchRec (x :: Int) = case <| x `mod` 2 |>+ of 0 -> Even+ | 1 -> Odd++ data SwitchTest = SwitchTest { arg :: Int, parity :: SwitchRec arg } |]++switchTest_name = "Switch"+switchTest_expected = BC.pack "150119154Even"+switchTest_got+ = (fromChunks+ $ (fromCL+ $ (switchTest_serialize+ $ SwitchTest {arg = 150119154, parity = Even})))+switchTest+ = TestCase (switchTest_expected @=? switchTest_got)++switchCycleTest_name = "Switch Cycle"+switchCycleTest = do+ ss <- replicateM sampleSize (runPadsGen switchTest_genM)+ let ss_serialized = map (BC.unpack . fromChunks . fromCL . switchTest_serialize) ss+ let ss_parsed = map (fst . fst . switchTest_parseS) ss_serialized+ return $ ss == ss_parsed++-- Test references to previously defined variables+[pads| data Dependent = Dependent { f :: Bits8 8+ , g :: Bytes <|fromIntegral f|> } |]++dependentSerTest_name = "Dependent Serialization"+dependentSerTest_expected+ = [BinaryChunk 7 8] ++ replicate 7 (CharChunk 'c')+dependentSerTest_got+ = fromCL $ dependent_serialize (Dependent 7 (B.pack [99,99,99,99,99,99,99]))+dependentSerTest+ = TestCase (dependentSerTest_expected @=? dependentSerTest_got)++dependentGenTest_name = "Dependent Generation"+dependentGenTest_invariant = do+ deps <- replicateM sampleSize (runPadsGen dependent_genM)+ return $ all (== True)+ (map (\dep -> (fromIntegral $ f dep) == (B.length $ g dep)) deps)+dependentGenTest+ = TestCase (assert dependentGenTest_invariant)++-- Test paramaterization of structures+[pads| data Param1 = Param1 { p1 :: Bits8 8+ , p2 :: Param2 p1}++ data Param2 (param :: Bits8) = Param2 { p3 :: Bytes <|fromIntegral param|> } |]++paramSerTest_name = "Parameterized Serialization"+paramSerTest_expected+ = [BinaryChunk 3 8, CharChunk 'c', CharChunk 'c', CharChunk 'c']+paramSerTest_got+ = (fromCL+ $ (param1_serialize (Param1 3 (Param2 (B.pack [99, 99, 99])))))+paramSerTest+ = TestCase (paramSerTest_expected @=? paramSerTest_got)++paramGenTest_name = "Parameterized Generation"+paramGenTest_invariant = do+ params <- replicateM sampleSize (runPadsGen param1_genM)+ return $ all (== True)+ (map (\par -> (fromIntegral $ p1 par) == (B.length (p3 (p2 par)))) params)+paramGenTest+ = TestCase (assert paramGenTest_invariant)++-- Obtain with custom generator (non-isomorphic types)+[pads| type Hex = obtain Word from String using <| (hexStrToWord, wordToHexStr) |> generator word_genM |]++type Word_md = Int_md++hexStrToWord :: Span -> (String, String_md) -> (Word, Word_md)+hexStrToWord _ (s, md) = ((fromIntegral . fst . (!! 0) . readHex) s, md)++wordToHexStr :: (Word, Word_md) -> (String, String_md)+wordToHexStr (i, md) = (showHex (fromIntegral i) "", md)++word_genM :: PadsGen st Word+word_genM = abs <$> randNum++hexObtainTest_name = "Hex Obtain"+hexObtainTest_expected+ = BC.pack "ab12"+hexObtainTest_got = fromChunks (fromCL $ (hex_serialize 43794))+hexObtainTest+ = TestCase (hexObtainTest_expected @=? hexObtainTest_got)++hexCycleTest_name = "Hex Cycle"+hexCycleTest = do+ hs <- replicateM sampleSize (runPadsGen hex_genM)+ let hs_serialized = map (BC.unpack . fromChunks . fromCL . hex_serialize) hs+ let hs_parsed = map (fst . fst . hex_parseS) hs_serialized+ return $ hs == hs_parsed++-- Test serialization from obtain decs (relies on their conversion functions),+-- along with creation of qualified serializer names (e.g. LE.int16_serialize)+[pads| type MyLEInt8 = LE.Int8 |]+littleInt8Test_name = "LE Int8"+littleInt8Test_expected = B.pack [1]+littleInt8Test_got = fromChunks $ fromCL $ myLEInt8_serialize 1+littleInt8Test = TestCase (littleInt8Test_expected @=? littleInt8Test_got)++[pads| type MyLEInt16 = LE.Int16 |]+littleInt16Test_name = "LE Int16"+littleInt16Test_expected = B.pack [0, 1]+littleInt16Test_got = fromChunks $ fromCL $ myLEInt16_serialize 256+littleInt16Test = TestCase (littleInt16Test_expected @=? littleInt16Test_got)++[pads| type MyLEInt32 = LE.Int32 |]+littleInt32Test_name = "LE Int32"+littleInt32Test_expected+ = B.pack [1, 1, 1, 0]+littleInt32Test_got = fromChunks $ fromCL $ myLEInt32_serialize 65793+littleInt32Test = TestCase (littleInt32Test_expected @=? littleInt32Test_got)++[pads| type MyBEInt8 = BE.Int8 |]+bigInt8Test_name = "BE Int8"+bigInt8Test_expected = B.pack [253]+bigInt8Test_got = fromChunks $ fromCL $ myBEInt8_serialize 253+bigInt8Test = TestCase (bigInt8Test_expected @=? bigInt8Test_got)++[pads| type MyBEInt16 = BE.Int16 |]+bigInt16Test_name = "BE Int16"+bigInt16Test_expected = B.pack [1, 0]+bigInt16Test_got = fromChunks $ fromCL $ myBEInt16_serialize 256+bigInt16Test = TestCase (bigInt16Test_expected @=? bigInt16Test_got)++[pads| type MyBEInt32 = BE.Int32 |]+bigInt32Test_name = "BE Int32"+bigInt32Test_expected+ = B.pack [0, 1, 1, 1]+bigInt32Test_got = fromChunks $ fromCL $ myBEInt32_serialize 65793+bigInt32Test = TestCase (bigInt32Test_expected @=? bigInt32Test_got)+++--fst <$> runStateT myGen 0 |> ,+myGenSt_M :: PadsGen Int [Int]+myGenSt_M = do+ putState 63+ fst <$> runStateT myGen 0++myWg3_M :: PadsGen Int Int+myWg3_M = do+ x <- getState+ return $ x - 21++-- Custom field-specific generators within a record+[pads| data WithGens = WithGens {+ wg1 :: [Int | ' '] generator <| myGenSt_M |> ,+ ' ',+ wg2 :: Char,+ ' ',+ wg3 :: Int generator <| myWg3_M |> } |] -- <| return 0 |> } |]++-- NB: 'randNumBetween 0 100' will result in test failure when empty lists are+-- generated, thanks to odd parsing behavior for separated lists:+--+-- [pads| type IntsNoSep = [Int]+-- type IntsSep = [Int | ' '] |]+-- (fst . fst . intsNoSep_parseS) "" == []+-- (fst . fst . intsSep_parseS) "" == [0]+myGen :: StateT Int (PadsGen st) [Int]+myGen = (ST.lift $ randNumBetween 1 100) >>= (flip replicateM increment)+ where+ increment = do+ x <- get+ put (x + 1)+ return x++runMyGen = runPadsGen (fst <$> runStateT myGen 0)++withGensTest_name = "Field Generators"+withGensTest = do+ wgs <- replicateM sampleSize (runPadsGenSt 0 withGens_genM)+ let wgs_serialized = map (BC.unpack . fromChunks . fromCL . withGens_serialize) wgs+ let wgs_parsed = map (fst . fst . withGens_parseS) wgs_serialized+ return $ wgs == wgs_parsed+++-- Large example, very heavy on bit-level values with custom generators+-- Lots of record nesting and parameterization, with some arithmetic for lengths++fI :: (Integral a, Num b) => a -> b+fI = fromIntegral++mtu :: Num a => a+mtu = 1460++[pads|+ type Bytes' (x :: Int) = Bytes <| max 0 x |>++ type PCAP = partition (PCAPHeader, [Packet]) using none++ data PCAPHeader = PCAPHeader {+ pchMagicNum :: Bits32 32 generator <| return 0xa1b2c3d4 |>,+ pchVersionMaj :: Bits16 16 generator <| return 2 |>,+ pchVersionMin :: Bits16 16 generator <| return 4 |> ,+ pchThisZone :: Bits32 32 generator <| return 0 |>,+ pchSigFigs :: Bits32 32 generator <| return 0 |>,+ pchSnapLen :: Bits32 32,+ pchNetwork :: Bits32 32 generator <| return 1 |>+ }++ data Packet = Packet {+ tsSec :: Bits32 32 generator <| liftIO $ floor <$> getPOSIXTime |>,+ tsUsec :: Bits32 32 generator <| randNumBound 999999999 |>,+ inclLen :: Bits32 32 generator <| return $ mtu + 54 |>,+ origLen :: Bits32 32 generator <| return inclLen |>,+ body :: Ethernet inclLen+ }++ data Ethernet (inclLen :: Bits32) = Ethernet {+ ethDst :: MacAddr,+ ethSrc :: MacAddr,+ ethType :: Bits16 16 generator <| return 2048 |>,+ ethPayload :: EthPayload <| (ethType, inclLen) |>+ }++ data MacAddr = MacAddr {+ constrain m1 :: Bits8 8 where <| m1 `mod` 2 == 0 |>,+ m2 :: Bits8 8,+ m3 :: Bits8 8,+ m4 :: Bits8 8,+ m5 :: Bits8 8,+ m6 :: Bits8 8+ }++ data EthPayload (ethType :: Bits16, inclLen :: Bits32) = case ethType of+ 2048 -> IPV4 {+ ipv4Version :: Bits8 4 generator <| return 4 |>,+ ipv4IHL :: Bits8 4 generator <| return 5 |>,+ ipv4DSCP :: Bits8 6,+ ipv4ECN :: Bits8 2,+ ipv4TotLen :: Bits16 16 generator <| return (max 0 $ (fI inclLen) - 14) |>,+ ipv4ID :: Bits16 16,+ ipv4Flags :: IPV4Flags,+ ipv4FragOff :: Bits16 13 generator <| return 0 |>,+ ipv4TTL :: Bits8 8,+ ipv4Protocol :: Bits8 8 generator <| return 6 |>,+ ipv4Cksum :: Bits16 16,+ ipv4Src :: Bits32 32,+ ipv4Dst :: Bits32 32,+ ipv4Opts :: Bytes <| 4 * (max 0 $ (fI ipv4IHL) - 5) |>,+ ipv4Payload :: IPV4Payload <| (ipv4Protocol, ipv4IHL, ipv4TotLen) |>+ }++ data IPV4Flags = IPV4Flags {+ ipv4Res :: BitBool generator <| return False |>,+ ipv4DF :: BitBool,+ ipv4MF :: BitBool generator <| return False |>+ }++ data IPV4Payload (prot :: Bits8, ipv4IHL :: Bits8, totLen :: Bits16) = TCP {+ tcpSrc :: Bits16 16 generator <| randElem [22,23,53,80,143,443] |>,+ tcpDst :: Bits16 16,+ tcpSeq :: Bits32 32,+ tcpAck :: Bits32 32,+ tcpOffset :: Bits8 4 generator <| return 5 |>,+ tcpReserved :: Bits8 3 generator <| return 0 |>,+ tcpFlags :: TCPFlags,+ tcpWindow :: Bits16 16,+ tcpCksum :: Bits16 16,+ tcpUrgPtr :: Bits16 16,+ tcpOptions :: Bytes <| 4 * (max 0 $ (fI tcpOffset) - 5) |>,+ tcpPayload :: Bytes' <| (fI totLen) - (fI $ (tcpOffset * 4) + (ipv4IHL * 4)) |>+ }++ data TCPFlags = TCPFlags {+ tcpNS :: BitBool,+ tcpCWR :: BitBool,+ tcpECE :: BitBool,+ tcpURG :: BitBool,+ tcpACK :: BitBool,+ tcpPSH :: BitBool,+ tcpRST :: BitBool generator <| return False |>,+ tcpSYN :: BitBool,+ tcpFIN :: BitBool+ }+|]++pCAPCycleTest_name = "PCAP Cycle"+pCAPCycleTest = do+ ps <- replicateM 5 (runPadsGen pCAP_genM)+ let ps_serialized = map (BC.unpack . fromChunks . fromCL . pCAP_serialize) ps+ let ps_parsed = map (fst . fst . pCAP_parseS) ps_serialized+ return $ ps == ps_parsed++writePCAP :: IO ()+writePCAP = do+ pcap <- runPadsGen pCAP_genM+ B.writeFile "data/fakePackets.pcap" $ (fromChunks . fromCL . pCAP_serialize) pcap+++-------------------------------------------------------------------------------+-- Unit testing of fromChunks function++emptyChunksTest_name = "Empty Chunks"+emptyChunksTest_expected = B.empty+emptyChunksTest_got = fromChunks []+emptyChunksTest+ = TestCase (emptyChunksTest_expected @=? emptyChunksTest_got)++charChunksTest_name = "CharChunks"+charChunksTest_expected = B.pack [100,99,98]+charChunksTest_got = fromChunks [CharChunk 'd',CharChunk 'c',CharChunk 'b']+charChunksTest+ = TestCase (charChunksTest_expected @=? charChunksTest_got)++binaryChunksTest_name = "Binary Chunks"+binaryChunksTest_expected = B.pack [100, 100]+binaryChunksTest_got+ = fromChunks+ [(BinaryChunk 12) 5, (BinaryChunk 8) 4, (BinaryChunk 6) 3,+ (BinaryChunk 4) 4]+binaryChunksTest+ = TestCase (binaryChunksTest_expected @=? binaryChunksTest_got)++bigBinaryChunksTest_name = "Big Binary Chunks"+bigBinaryChunksTest_expected+ = B.concat [ B.replicate 7 0 `B.append` B.pack [1]+ , B.replicate 15 0 `B.append` B.pack [2]+ , B.replicate 31 0 `B.append` B.pack [6]+ ]+bigBinaryChunksTest_got+ = fromChunks [BinaryChunk 1 64, BinaryChunk 2 128, BinaryChunk 3 255]+bigBinaryChunksTest+ = TestCase (bigBinaryChunksTest_expected @=? bigBinaryChunksTest_got)++bigBinaryChunks2Test_name = "Big Binary Chunks 2"+bigBinaryChunks2Test_expected+ = B.concat [ B.replicate 8 255+ , B.pack [128] `B.append` B.replicate 15 0+ , B.replicate 31 255 `B.append` B.pack [254]+ ]+bigBinaryChunks2Test_got+ = fromChunks [ BinaryChunk (2^64 - 1) 64+ , BinaryChunk (2^127) 128+ , BinaryChunk (2^255 - 1) 255+ ]+bigBinaryChunks2Test+ = TestCase (bigBinaryChunks2Test_expected @=? bigBinaryChunks2Test_got)++misalignedChunksTest_name = "Misaligned Chunks"+misalignedChunksTest_expected = B.pack [100, 96]+misalignedChunksTest_got+ = fromChunks+ [(BinaryChunk 12) 5, (BinaryChunk 8) 4, (BinaryChunk 6) 3]+misalignedChunksTest+ = TestCase+ (misalignedChunksTest_expected+ @=? misalignedChunksTest_got)++misalignedChunks2Test_name = "Misaligned Chunks 2"+misalignedChunks2Test_expected = B.pack [192]+misalignedChunks2Test_got = fromChunks [(BinaryChunk 3) 2]+misalignedChunks2Test+ = TestCase (misalignedChunks2Test_expected @=? misalignedChunks2Test_got)++mixedChunksTest_name = "Mixed Misaligned Chunks"+mixedChunksTest_expected = B.pack [76, 128, 200]+mixedChunksTest_got+ = fromChunks+ [(BinaryChunk 2) 3, CharChunk 'd', (BinaryChunk 1) 6,+ (BinaryChunk 2) 2, (BinaryChunk 1) 2]+mixedChunksTest+ = TestCase (mixedChunksTest_expected @=? mixedChunksTest_got)++mixedChunks2Test_name = "Mixed Aligned Chunks"+mixedChunks2Test_expected = B.pack [97, 1, 98]+mixedChunks2Test_got+ = fromChunks [CharChunk 'a', BinaryChunk 1 8, CharChunk 'b']+mixedChunks2Test+ = TestCase (mixedChunks2Test_expected @=? mixedChunks2Test_got)++-- Ensure theoretically equivalent binary and character chunks behave+-- equivalently, individually and together in a list+binCharEquivTest_name = "Binary/Char Chunk Equivalence"+binCharEquivTest = let+ bcs = [ [BinaryChunk i 8] | i <- [0..255]]+ ccs = [ [CharChunk (word8ToChr c)] | c <- [0..255]]+ bcs' = map fromChunks bcs+ ccs' = map fromChunks ccs+ bcs2 = [BinaryChunk i 8 | i <- [0..255]]+ ccs2 = [CharChunk (word8ToChr c) | c <- [0..255]]+ bcs2' = fromChunks bcs2+ ccs2' = fromChunks ccs2+ in (return :: a -> IO a) (bcs' == ccs' && bcs2' == ccs2')++tests = TestList [ charTest_name ~: charTest+ , charCycleTest_name ~: charCycleTest+ , intTest_name ~: intTest+ , intCycleTest_name ~: intCycleTest+ , bits8Test_name ~: bits8Test+ , bits8CycleTest_name ~: bits8CycleTest+ , bits8MisalignedTest_name ~: bits8MisalignedTest+ , bits16Test_name ~: bits16Test+ , bits16CycleTest_name ~: bits16CycleTest+ , bits16MisalignedTest_name ~: bits16MisalignedTest+ , bits32Test_name ~: bits32Test+ , bits32CycleTest_name ~: bits32CycleTest+ , bits64Test_name ~: bits64Test+ , bits64CycleTest_name ~: bits64CycleTest+ , bitBoolTest_name ~: bitBoolTest+ , bitBoolCycleTest_name ~: bitBoolCycleTest+ , bitFieldCycleTest_name ~: bitFieldCycleTest+ , bytesTest_name ~: bytesTest+ , myStringCTest_name ~: myStringCTest+ , myStringCCycleTest_name ~: myStringCCycleTest+ , myTupleTest_name ~: myTupleTest+ , myTupleCycleTest_name ~: myTupleCycleTest+ , byteTest_name ~: byteTest+ , byteCycleTest_name ~: byteCycleTest+ , twoBytesTest_name ~: twoBytesTest+ , twoBytesCycleTest_name ~: twoBytesCycleTest+ , nestedTupleTest_name ~: nestedTupleTest+ , constrainedStringTest_name ~: constrainedStringTest+ , constrainedGenTest_name ~: constrainedGenTest+ , simpleConstraintTest_name ~: simpleConstraintTest+ , simpleConstraintTest2_name ~: simpleConstraintTest2+ , regularListTest_name ~: regularListTest+ , sepListTest_name ~: sepListTest+ , sepTermListTest_name ~: sepTermListTest+ , sepTermListBytesTest_name ~: sepTermListBytesTest+ , sepTermListLitTest_name ~: sepTermListLitTest+ , sepTermListLitCycleTest_name ~: sepTermListLitCycleTest+ , lenListTest_name ~: lenListTest+ , lenListCycleTest_name ~: lenListCycleTest+ , sepLenListTest_name ~: sepLenListTest+ , sepLenListCycleTest_name ~: sepLenListCycleTest+ , pixelTest_name ~: pixelTest+ , pixelBytesTest_name ~: pixelBytesTest+ , pixelCycleTest_name ~: pixelCycleTest+ , recordConstantsTest_name ~: recordConstantsTest+ , constantsCycleTest_name ~: constantsCycleTest+ , fooFooTest_name ~: fooFooTest+ , fooBarTest_name ~: fooBarTest+ , myConstr1WithArgsTest_name ~: myConstr1WithArgsTest+ , myConstr2NoArgsTest_name ~: myConstr2NoArgsTest+ , myConstr3TVArgsTest_name ~: myConstr3TVArgsTest+ , myConstr4NoArgsTest_name ~: myConstr4NoArgsTest+ --, myConstrCycleTest_name ~: myConstrCycleTest+ , myListEmptyTest_name ~: myListEmptyTest+ , myListNonemptyTest_name ~: myListNonemptyTest+ , myListCycleTest_name ~: myListCycleTest+ , nTTest_name ~: nTTest+ , nTCycleTest_name ~: nTCycleTest+ , switchTest_name ~: switchTest+ , switchCycleTest_name ~: switchCycleTest+ , dependentSerTest_name ~: dependentSerTest+ , dependentGenTest_name ~: dependentGenTest+ , paramSerTest_name ~: paramSerTest+ , paramGenTest_name ~: paramGenTest+ , hexObtainTest_name ~: hexObtainTest+ , hexCycleTest_name ~: hexCycleTest+ , littleInt8Test_name ~: littleInt8Test+ , littleInt16Test_name ~: littleInt16Test+ , littleInt32Test_name ~: littleInt32Test+ , bigInt8Test_name ~: bigInt8Test+ , bigInt16Test_name ~: bigInt16Test+ , bigInt32Test_name ~: bigInt32Test+ , withGensTest_name ~: withGensTest+ , pCAPCycleTest_name ~: pCAPCycleTest+ , emptyChunksTest_name ~: emptyChunksTest+ , charChunksTest_name ~: charChunksTest+ , binaryChunksTest_name ~: binaryChunksTest+ , bigBinaryChunksTest_name ~: bigBinaryChunksTest+ , bigBinaryChunks2Test_name ~: bigBinaryChunks2Test+ , misalignedChunksTest_name ~: misalignedChunksTest+ , misalignedChunks2Test_name ~: misalignedChunks2Test+ , mixedChunksTest_name ~: mixedChunksTest+ , mixedChunks2Test_name ~: mixedChunks2Test+ , binCharEquivTest_name ~: binCharEquivTest+ ]++test = runTestTT tests++main :: IO Counts+main = test
@@ -0,0 +1,60 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,+ MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}+module Extensible where++import Language.Pads.Padsc+import Language.Pads.Syntax as PS+import Language.Pads.MetaData+import Language.Pads.Generic+import Language.Pads.PadsParser+import Language.Pads.CoreBaseTypes+import Language.Pads.TH+import qualified Language.Pads.Errors as E+import qualified Language.Pads.Source as S+import Language.Pads.PadsPrinter+import Language.Pads.Generation++import Language.Haskell.TH+-- import Language.Haskell.TH.Syntax++import Data.Data+import Data.Char+import qualified Data.Map as M+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import Control.Monad+import Language.Haskell.TH.Syntax+import qualified System.Random.MWC as MWC+import qualified Debug.Trace as D++myCompiler :: [PadsDecl] -> Q [Dec]+myCompiler (x:xs) = compileSingle x+myCompiler [] = pure []++fI = fromIntegral++mkKarl name typeParams =+ [d| $(varP $ mkName $ "karl_" ++ name) = $(litE $ integerL $ fI $ length typeParams) |]++compileSingle :: PadsDecl -> Q [Dec]+compileSingle p@(PadsDeclType name typeParams pat inner generator) =+ do k <- mkKarl name typeParams+ ds <- make_pads_declarations [transform p]+ pure $ k ++ ds+compileSingle p@(PadsDeclData name typeParams pat inner derivers) = mkKarl name typeParams+compileSingle p@(PadsDeclNew name typeParams pat inner derivers) = mkKarl name typeParams+compileSingle p@(PadsDeclObtain name typeParams inner invers generator) = mkKarl name typeParams++transform (PadsDeclType name typeParams pat inner generator)+ = PadsDeclType ("Karl_" ++ name) typeParams pat (transformInner inner) generator+transform _ = error "unimplemented"++transformInner (PTuple tys) = PTuple $ map transformInner tys+transformInner (PTycon qs)+ | qs == ["Int"] = PTycon ["Char"]+ | otherwise = PTycon qs+transformInner rest = rest++myQuoter = padsE myCompiler+
@@ -0,0 +1,19 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TypeSynonymInstances, TemplateHaskell, QuasiQuotes,+ MultiParamTypeClasses, FlexibleInstances, UndecidableInstances,+ DeriveDataTypeable, ScopedTypeVariables #-}+module Main where+import Language.Pads.Padsc+import Language.Haskell.TH++import Extensible++[myQuoter| type Foo x y z = (Int, '|', Int) |]++main :: IO ()+main = do+ if (karl_Foo == 3) -- because Foo has 3 type parameters+ then print "Success (:"+ else print "Failure ):"+ print $ (fst . fst . karl_Foo_parseS 0 0 0) "a|b"+ print $ (fst . fst . foo_parseS 7 8 9) "3|4"+
@@ -1,161 +1,205 @@--- pads-haskell.cabal auto-generated by cabal init. For additional options,--- see--- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.--- The name of the package.-Name: pads-haskell---- The package version. See the Haskell package versioning policy--- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for--- standards guiding when and how versions should be incremented.-Version: 0.0.0.1---- A short (one-line) description of the package.-Synopsis: PADS data description language for Haskell---- A longer description of the package.-Description: Massive amounts of useful data are stored and processed in- ad hoc formats for which common tools like parsers,- printers, query engines and format converters are not readily- available. Pads/Haskell is a domain-specific language that- facilitates the generation of data processing tools for ad hoc- formats. Pads/Haskell includes features such as- dependent, polymorphic and recursive datatypes, which allow- programmers to describe the syntax and semantics of ad hoc data in a- concise, easy-to-read notation.---- URL for the project homepage or repository.-Homepage: http://www.padsproj.org---- The license under which the package is released.-License: BSD3---- The file containing the license text.-License-file: LICENSE---- The package author(s).-Author: Kathleen Fisher and John Launchbury---- An email address to which users can send suggestions, bug reports,--- and patches.-Maintainer: kathleen.fisher@gmail.com---- A copyright notice.--- Copyright:---Category: Language--Build-type: Simple---- Extra files to be distributed with the package, such as examples or--- a README.-Extra-source-files: Examples/First.hs, Examples/AI.hs, Examples/Binary.hs,- Examples/data/README- Examples/data/test_file- Examples/data/ai.3000, Examples/data/ai.big,- Examples/data/binary,- Examples/data/a2b.c, Examples/data/calls10.a, Examples/data/calls10.b,- Examples/data/genBin.c, Examples/data/binTest.a, Examples/data/binTest.b- Documentation/Info/PADS-Index.txt- Documentation/Info/PackagesUsedInPads.txt- Documentation/Info/Pads-grammar.tex- Test/data/maps0---- Constraint on the version of Cabal needed to build this package.-Cabal-version: >=1.10---Library- -- Modules exported by the library.- exposed-modules: Language.Pads.GenPretty, Language.Pads.Padsc,- Language.Pads.BaseTypes, Language.Pads.Quote,- Language.Pads.Syntax, Language.Pads.Parser,- Language.Pads.Generic, Language.Pads.RegExp- Language.Pads.Pretty, Language.Pads.Source,- Language.Pads.TH, Language.Pads.Testing,- Language.Pads.Library.BinaryUtilities,- Language.Pads.Library.Native,- Language.Pads.Library.BigEndian,- Language.Pads.Library.LittleEndian,- Language.Pads.CodeGen,- Language.Pads.CoreBaseTypes,- Language.Pads.Errors,- Language.Pads.MetaData,- Language.Pads.PadsParser,- Language.Pads.PadsPrinter-- -- Packages needed in order to build this package.- build-depends: base >= 4.7 && < 5.0,- syb >= 0.7 && < 0.8,- containers >= 0.5.5.1 && < 0.6,- template-haskell >= 2.9 && < 2.14,- Glob >= 0.9.2 && < 0.10,- regex-posix >= 0.95.2 && < 0.96,- bytestring >= 0.10.4 && < 0.11,- haskell-src >= 1.0.1.6 && < 1.1,- haskell-src-meta >= 0.8.0.2 && < 0.9,- parsec >= 3.1.0 && < 3.2,- mainland-pretty >= 0.6.1 && < 0.7,- HUnit >= 1.6.0.0 && < 1.7,- byteorder >= 1.0.4 && < 1.1,- old-locale >= 1.0.0.6 && < 1.1,- time >= 1.8.0.2 && < 1.9,- random >= 1.1 && < 1.2,- normaldistribution >= 1.1.0.3 && < 1.2,- th-lift >= 0.7.8 && < 0.8,- transformers+cabal-version: 1.12+name: pads-haskell+version: 0.1.0.0+license: MIT+license-file: LICENSE+copyright: 2011 Kathleen Fisher & John Launchbury+maintainer: karl@cs.tufts.edu+author: Kathleen Fisher and John Launchbury+homepage: https://github.com/padsproj/pads-haskell#readme+bug-reports: https://github.com/padsproj/pads-haskell/issues+synopsis: PADS data description language for Haskell.+description:+ Please see the README on Github at <https://github.com/padsproj/pads-haskell#readme>+category: Language+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md+ examples/First.hs+ examples/AI.hs+ examples/Binary.hs+ extended/Extensible.hs+ extended/Main.hs+ examples/data/README+ examples/data/test_file+ examples/data/ai.3000+ examples/data/ai.big+ examples/data/binary+ examples/data/a2b.c+ examples/data/calls10.a+ examples/data/calls10.b+ examples/data/genBin.c+ examples/data/binTest.a+ examples/data/binTest.b+ examples/data/maps0+ Documentation/Info/PADS-Index.txt+ Documentation/Info/PackagesUsedInPads.txt+ Documentation/Info/Pads-grammar.tex - -- Modules not exported by this package.+source-repository head+ type: git+ location: https://github.com/padsproj/pads-haskell - default-language: Haskell2010+library+ exposed-modules:+ Language.Pads.BaseTypes+ Language.Pads.CodeGen+ Language.Pads.CoreBaseTypes+ Language.Pads.Errors+ Language.Pads.Generation+ Language.Pads.Generic+ Language.Pads.GenPretty+ Language.Pads.MetaData+ Language.Pads.Padsc+ Language.Pads.PadsParser+ Language.Pads.PadsPrinter+ Language.Pads.Parser+ Language.Pads.Pretty+ Language.Pads.Quote+ Language.Pads.RegExp+ Language.Pads.Source+ Language.Pads.Syntax+ Language.Pads.Testing+ Language.Pads.TH+ Language.Pads.Library.BigEndian+ Language.Pads.Library.BinaryUtilities+ Language.Pads.Library.LittleEndian+ Language.Pads.Library.Native+ hs-source-dirs: src+ other-modules:+ Paths_pads_haskell+ default-language: Haskell2010+ build-depends:+ HUnit >=1.6 && <1.8,+ base >=4.7 && <5,+ byteorder >=1.0.4 && <1.1,+ bytestring ==0.10.*,+ containers >=0.5.10 && <0.7,+ ghc-prim >=0.5.3 && <0.6,+ haskell-src-meta ==0.8.*,+ mainland-pretty >=0.6.1 && <0.8,+ mtl >=2.2.2 && <3,+ mwc-random >=0.13.6.0 && <0.15,+ parsec >=3.1.13 && <3.2,+ random ==1.1.*,+ regex-posix >=0.95.2 && <0.96,+ syb ==0.7.*,+ template-haskell >=2.14.0.0 && <=2.15,+ th-lift >=0.7.11 && <0.8,+ time >=1.7.0 && <1.8.1,+ transformers ==0.5.* - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.- -- Build-tools:+test-suite examples+ type: exitcode-stdio-1.0+ main-is: Main.hs+ hs-source-dirs: examples+ other-modules:+ Addrs+ AI+ All+ Arith+ Binary+ DFA+ DFAC+ DOS+ First+ FirstPads+ FullPCAP+ HmmPlusOrig+ HPROF+ IntPair+ One+ PCAPBodyFill+ PCAPBodyGen+ Pnm+ Proc+ Regression+ Small+ VCard+ VCardInfinite+ Paths_pads_haskell+ default-language: Haskell2010+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ HUnit >=1.6 && <1.8,+ QuickCheck >=2.10.1 && <2.13,+ base >=4.7 && <5,+ byteorder >=1.0.4 && <1.1,+ bytestring ==0.10.*,+ containers >=0.5.10 && <0.7,+ ghc-prim >=0.5.3 && <0.6,+ haskell-src-meta ==0.8.*,+ mainland-pretty >=0.6.1 && <0.8,+ mtl >=2.2.2 && <2.3,+ mwc-random >=0.13.6.0 && <0.15,+ pads-haskell -any,+ parsec >=3.1.13 && <3.2,+ random ==1.1.*,+ regex-posix >=0.95.2 && <0.96,+ syb ==0.7.*,+ template-haskell >=2.14.0.0 && <=2.15,+ test-framework >=0.8.2 && <0.9,+ test-framework-hunit >=0.3.0 && <0.4,+ test-framework-quickcheck2 >=0.3.0 && <0.4,+ th-lift >=0.7.11 && <0.8,+ time >=1.7.0 && <1.8.1,+ transformers ==0.5.* -Flag debug- Description: Adds debug logging- Manual: True- Default: False- +test-suite extended+ type: exitcode-stdio-1.0+ main-is: Main.hs+ hs-source-dirs: extended+ other-modules:+ Extensible+ Paths_pads_haskell+ default-language: Haskell2010+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ HUnit >=1.6 && <1.8,+ base >=4.7 && <5,+ byteorder >=1.0.4 && <1.1,+ bytestring ==0.10.*,+ containers >=0.5.10 && <0.7,+ ghc-prim >=0.5.3 && <0.6,+ haskell-src-meta ==0.8.*,+ mainland-pretty >=0.6.1 && <0.8,+ mtl >=2.2.2 && <3,+ mwc-random >=0.13.6.0 && <0.15,+ pads-haskell -any,+ parsec >=3.1.13 && <3.2,+ random ==1.1.*,+ regex-posix >=0.95.2 && <0.96,+ syb ==0.7.*,+ template-haskell >=2.14.0.0 && <=2.15,+ th-lift >=0.7.11 && <0.8,+ time >=1.7.0 && <1.8.1,+ transformers ==0.5.* -Test-Suite examples- Type: exitcode-stdio-1.0- Main-Is: Test/Examples.hs- if flag(debug)- ghc-options: -ddump-splices- build-depends: base- , old-locale, haskell-src, template-haskell- , mainland-pretty, containers, time, syb, parsec- , haskell-src-meta, Glob, bytestring, regex-posix- , QuickCheck, HUnit- , Cabal- , test-framework- , test-framework-hunit- , test-framework-quickcheck2- , directory, byteorder- , th-lift, transformers, mtl- default-language: Haskell2010- other-modules: Examples.Proc, Examples.First, Examples.AI, Examples.Binary- , Examples.FirstPads- , Language.Pads.Testing- , Language.Pads.BaseTypes- , Language.Pads.CodeGen- , Language.Pads.CoreBaseTypes- , Language.Pads.Errors- , Language.Pads.GenPretty- , Language.Pads.Generic- , Language.Pads.MetaData- , Language.Pads.PadsParser- , Language.Pads.PadsPrinter- , Language.Pads.Padsc- , Language.Pads.Parser- , Language.Pads.Pretty- , Language.Pads.Quote- , Language.Pads.RegExp- , Language.Pads.Source- , Language.Pads.Syntax- , Language.Pads.TH- , Language.Pads.Library.BigEndian- , Language.Pads.Library.BinaryUtilities- , Language.Pads.Library.LittleEndian- , Language.Pads.Library.Native+test-suite gen+ type: exitcode-stdio-1.0+ main-is: examples/gen-testing/Main.hs+ other-modules:+ Paths_pads_haskell+ default-language: Haskell2010+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ HUnit >=1.6 && <1.8,+ base >=4.7 && <5,+ byteorder >=1.0.4 && <1.1,+ bytestring ==0.10.*,+ containers >=0.5.10 && <0.7,+ ghc-prim >=0.5.3 && <0.6,+ haskell-src-meta ==0.8.*,+ mainland-pretty >=0.6.1 && <0.8,+ mtl >=2.2.2 && <3,+ mwc-random >=0.13.6.0 && <0.15,+ pads-haskell -any,+ parsec >=3.1.13 && <3.2,+ random ==1.1.*,+ regex-posix >=0.95.2 && <0.96,+ syb ==0.7.*,+ template-haskell >=2.14.0.0 && <=2.15,+ th-lift >=0.7.11 && <0.8,+ time >=1.7.0 && <1.8.1,+ transformers ==0.5.*
@@ -0,0 +1,158 @@+{-# LANGUAGE FlexibleContexts, TypeFamilies, TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,+ FlexibleInstances, TypeSynonymInstances, UndecidableInstances, LambdaCase #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.BaseTypes+ Description : Base types provided by Pads+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ Some useful Pads types (parsers) implemented by the code generator in lieu of+ writing them by hand.++-}++module Language.Pads.BaseTypes where++import Language.Pads.Source+import Language.Pads.Errors+import Language.Pads.Generic+import Language.Pads.MetaData+import Language.Pads.CoreBaseTypes+import Language.Pads.Quote+import Language.Pads.RegExp+import Language.Pads.PadsPrinter+import Language.Pads.Generation+import Data.Time+--import System.Locale as Locale+import Text.PrettyPrint.Mainland (text)+import Text.PrettyPrint.Mainland.Class++import qualified Data.Char as C+import qualified Data.List as L+import Data.Data+import qualified Data.ByteString as B++[pads|+-- string that stops in a newline+type StringEOR = [Char] terminator EOR+type Line a = (a, EOR)+type StringLn = [Char] terminator (Try EOR)+type StringLnP (p :: String -> Bool) = constrain s :: StringLn where <| p s |>+type StringESCLn (p :: (Char, [Char])) = StringPESC <|(True, p)|>+type StringESC (p :: (Char, [Char])) = StringPESC <|(False, p)|>++data PMaybe a = PJust a+ | PNothing Void+obtain Maybe a from PMaybe a using <|(pm2m,m2pm)|>++|]++-- | Pads maybe to Haskell maybe+pm2m :: Span -> (PMaybe a, PMaybe_md a_md) -> (Maybe a, Maybe_md a_md)+pm2m p (PJust x, md) = (Just x, md)+pm2m p (PNothing,md) = (Nothing,md)++-- | Haskell maybe to Pads maybe+m2pm :: (Maybe a, Maybe_md a_md) -> (PMaybe a, PMaybe_md a_md)+m2pm (Just x, md) = (PJust x, md)+m2pm (Nothing,md) = (PNothing,md)++maybe_genM :: PadsGen st a -> PadsGen st (Maybe a)+maybe_genM x = pMaybe_genM x >>= (\case PJust a -> return $ Just a+ PNothing -> return $ Nothing)++[pads|+type Lit (x::String) = (Void, x)+type LitRE (x::RE) = (Void, x)+|]++[pads| obtain Bool from Bits8 1 using <| (bits8ToBool, boolToBits8) |> generator bitBool_genM |]++bits8ToBool :: Span -> (Bits8, Bits8_md) -> (Bool, Bool_md)+bits8ToBool _ (b, md) = (b == 1, md)++boolToBits8 :: (Bool, Bool_md) -> (Bits8, Bits8_md)+boolToBits8 (b, md) = ((fromIntegral . fromEnum) b, md)+++[pads| type DateFSE (fmt :: String, se :: RE) = obtain UTCTime from StringSE se using <| (strToUTC fmt, utcToStr fmt) |>+ type DateFC (fmt::String, c::Char) = DateFSE <|(fmt, RE ("[" ++ [c] ++ "]")) |> |]++-- | Coordinated universal time Pads metadata type+type UTCTime_md = Base_md+instance Pretty UTCTime where+ ppr utc = text (show utc)++-- | UTC parser from a string based on Haskell builtin UTC parser.+strToUTC :: String -> Span -> (StringSE, Base_md) -> (UTCTime, Base_md)+strToUTC fmt pos (input, input_bmd) =+ case parseTimeM True Data.Time.defaultTimeLocale fmt input of+ Nothing -> (gdef, mergeBaseMDs [errPD, input_bmd])+ Just t -> (t, input_bmd)+ where+ errPD = mkErrBasePD (TransformToDstFail "DateFSE" input " (conversion failed)") (Just pos)++-- | Default time of: 0h Nov 17, 1858+uTCTime_def = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 0)++-- | Format a UTC instance as a string.+utcToStr :: String -> (UTCTime, Base_md) -> (StringSE, Base_md)+utcToStr fmt (utcTime, bmd) = (formatTime Data.Time.defaultTimeLocale fmt utcTime, bmd)+++[pads| type TimeZoneSE (se :: RE) = obtain TimeZone from StringSE se using <| (strToTz, tzToStr) |>+ type TimeZoneC (c::Char) = TimeZoneSE <|RE ("[" ++ [c] ++ "]") |> |]++type TimeZone_md = Base_md+instance Pretty TimeZone where+ ppr tz = text (show tz)++-- | Timezone parser+strToTz :: Span -> (StringSE, Base_md) -> (TimeZone, Base_md)+strToTz pos (input, input_bmd) =+ case parseTimeM True Data.Time.defaultTimeLocale "%z" input of+ Nothing -> (gdef, mergeBaseMDs [mkErrBasePD (TransformToDstFail "TimeZoneSE" input " (conversion failed)") (Just pos), input_bmd])+ Just t -> (t, input_bmd)++-- | Timezone formatter+tzToStr :: (TimeZone, Base_md) -> (StringSE, Base_md)+tzToStr (tz, bmd) = (h ++ ":" ++ m, bmd)+ where (h,m) = splitAt 3 (show tz)++timeZone_def = utc++[pads| type Phex32FW (size :: Int) = obtain Int from StringFW size using <| (hexStr2Int,int2HexStr size) |> |]++-- | Transform a hexadecimal string to an int+hexStr2Int :: Span -> (StringFW, Base_md) -> (Int, Base_md)+hexStr2Int src_pos (s,md) = if good then (intList2Int ints 0, md)+ else (0, mkErrBasePD (TransformToDstFail "StrHex" s " (non-hex digit)") (Just src_pos))+ where+ hc2int c = if C.isHexDigit c then (C.digitToInt c,True) else (0,False)+ (ints,bools) = unzip (map hc2int s)+ good = (L.and bools) && (length ints > 0)+ intList2Int digits a = case digits of+ [] -> a+ (d:ds) -> intList2Int ds ((16 * a) + d)++-- | Transform an int into a hexadecimal string+int2HexStr :: Int -> (Int, Base_md) -> (StringFW, Base_md)+int2HexStr size (x,md)+ | length result == size && wasPos = (result, md)+ | not wasPos = (Prelude.take size result,+ mkErrBasePD (TransformToSrcFail "StrHex" (show x) (" (Expected positive number)")) Nothing)+ | otherwise = (Prelude.take size result,+ mkErrBasePD (TransformToSrcFail "StrHex" (show x) (" (too big to fit in "++ (show size) ++" characters)")) Nothing)+ where+ cvt rest a = if rest < 16 then {- reverse $ -} (C.intToDigit rest) : a+ else cvt (rest `div` 16) (C.intToDigit (rest `mod` 16) : a)+ (wasPos,x') = if x < 0 then (False, -x) else (True, x)+ temp = cvt x' []+ padding = size - (length temp)+ stutter c n = if n <= 0 then [] else c : (stutter c (n-1))+ result = (stutter '0' padding) ++ temp
@@ -0,0 +1,1713 @@+{-# LANGUAGE TupleSections, ViewPatterns, TemplateHaskell, NamedFieldPuns, ScopedTypeVariables,+ RecordWildCards, UndecidableInstances #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.CodeGen+ Description : Template Haskell based code generator+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ To the best of my knowledge, all functions defined herein are only ever run at+ compile time. These compile time functions are intended to be used in a+ quasiquoted context where the runtime system support modules have been properly+ imported. See "Examples.First" for the necessary imports.++ The crucial piece of the code generator is 'genParseTy', which translates Pads+ syntactic forms into Haskell code for parsing them.++-}+module Language.Pads.CodeGen where++import Language.Pads.Syntax as PS+import Language.Pads.MetaData+import Language.Pads.Generic+import Language.Pads.PadsParser+import Language.Pads.CoreBaseTypes+import Language.Pads.TH+import qualified Language.Pads.Errors as E+import qualified Language.Pads.Source as S+import Language.Pads.PadsPrinter+import Language.Pads.Generation++import Language.Haskell.TH+-- import Language.Haskell.TH.Syntax++import Data.Data+import Data.Char+import qualified Data.Map as M+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import Control.Monad+import Language.Haskell.TH.Syntax --(lift, Name, NameFlavour(..), OccName)+import qualified System.Random.MWC as MWC+import qualified Debug.Trace as D++-- |+type BString = S.RawStream++-- | A function passed into the code generator which gets called on data type+-- declarations and returns a list of standalone-deriving declarations.+-- Presently this is unused by Pads.+type Derivation = Dec -> Q [Dec]++-- | Top level code gen function from Pads decls to Haskell decls+make_pads_declarations :: [PadsDecl] -> Q [Dec]+make_pads_declarations = make_pads_declarations' (const $ return [])++-- | Top level code gen function from Pads decls to Haskell expression with just+-- the PADS AST (no parser codegen)+make_pads_asts :: [PadsDecl] -> Q Exp+make_pads_asts = let+ mpa pd@(PadsDeclType n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]+ mpa pd@(PadsDeclData n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]+ mpa pd@(PadsDeclNew n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]+ mpa pd@(PadsDeclObtain n _ _ _ _) = [| ($(litE $ stringL n), $(lift pd)) |]+ in listE . (map mpa)++-- | Top level code gen function from Pads decls to Haskell decls with the+-- specified list of type classes for all of the generated Pads types to derive.+make_pads_declarations' :: Derivation -> [PadsDecl] -> Q [Dec]+make_pads_declarations' derivation ds = fmap concat (mapM (genPadsDecl derivation) ds)++-------------------------------------------------------------------------------+-- * Generating Declarations and Code from Individual Pads Declarations++genPadsDecl :: Derivation -> PadsDecl -> Q [Dec]+-- ^ Generate all the top level Haskell declarations associated with a single+-- Pads declaration.+genPadsDecl derivation pd@(PadsDeclType name args pat padsTy gen) = do+ let typeDecs = mkTyRepMDDecl name args padsTy+ parseM <- genPadsParseM name args pat padsTy+ parseS <- genPadsParseS name args pat+ printFL <- genPadsPrintFL name args pat padsTy+ genM <- genPadsGenM name args pat padsTy gen+ serialize <- genPadsSerialize name args pat padsTy+ def <- genPadsDef name args pat padsTy+ let sigs = mkPadsSignature name args (fmap patType pat)+ ast <- astDecl name pd+ return $ typeDecs ++ parseM ++ parseS ++ printFL ++ genM ++ serialize ++ def ++ sigs++genPadsDecl derivation pd@(PadsDeclData name args pat padsData derives) = do+ dataDecs <- mkDataRepMDDecl derivation name args padsData derives+ parseM <- genPadsDataParseM name args pat padsData+ parseS <- genPadsParseS name args pat+ printFL <- genPadsDataPrintFL name args pat padsData+ genM <- genPadsDataGenM name args pat padsData+ serialize <- genPadsDataSerialize name args pat padsData+ def <- genPadsDataDef name args pat padsData+ let instances = mkPadsInstance name args (fmap patType pat)+ let sigs = mkPadsSignature name args (fmap patType pat)+ ast <- astDecl name pd+ return $ dataDecs ++ parseM ++ parseS ++ printFL ++ genM ++ serialize ++ def ++ instances ++ sigs++genPadsDecl derivation pd@(PadsDeclNew name args pat branch derives) = do+ dataDecs <- mkNewRepMDDecl derivation name args branch derives+ parseM <- genPadsNewParseM name args pat branch+ parseS <- genPadsParseS name args pat+ printFL <- genPadsNewPrintFL name args pat branch+ genM <- genPadsNewGenM name args pat branch+ serialize <- genPadsNewSerialize name args pat branch+ def <- genPadsNewDef name args pat branch+ let instances = mkPadsInstance name args (fmap patType pat)+ let sigs = mkPadsSignature name args (fmap patType pat)+ ast <- astDecl name pd+ return $ dataDecs ++ parseM ++ parseS ++ printFL ++ genM ++ serialize ++ def ++ instances ++ sigs++genPadsDecl derivation pd@(PadsDeclObtain name args padsTy exp genM) = do+ let mdDec = mkObtainMDDecl name args padsTy+ parseM <- genPadsObtainParseM name args padsTy exp+ parseS <- genPadsParseS name args Nothing+ printFL <- genPadsObtainPrintFL name args padsTy exp+ genM <- genPadsObtainGenM name args padsTy exp genM+ serialize <- genPadsObtainSerialize name args padsTy exp+ def <- genPadsObtainDef name args padsTy exp+ let sigs = mkPadsSignature name args Nothing+ ast <- astDecl name pd+ return $ mdDec ++ parseM ++ parseS ++ printFL ++ genM ++ serialize ++ def ++ sigs++-- | A Haskell declaration containing the literal Pads AST representation of a+-- Pads description (the syntax of Pads encoded as Haskell data constructors)+astDecl name pd = funD (mkName $ "ast_" ++ name) [clause [] (normalB $ lift pd) []]++-- | The Haskell 'Type' of a Haskell pattern 'Pat'.+patType :: Pat -> Type+patType p = case p of+ LitP lit -> case lit of+ CharL c -> VarT ''Char+ StringL s -> VarT ''String+ TupP ps -> mkTupleT (map patType ps)+ SigP p t -> t+ ParensP p -> patType p+ otherwise -> error $ show p++-------------------------------------------------------------------------------+-- * Generating Rep/MD Type Declarations++-- | Make the type declarations for the representation and the metadata of a+-- Pads-defined type, @'PadsTy'@.+mkTyRepMDDecl :: UString -> [UString] -> PadsTy -> [Dec]+mkTyRepMDDecl name args ty = [repType, mdType]+ where+ repType = TySynD (mkRepName name) tyArgs (mkRepTy ty)+ mdType = TySynD (mkMDName name) tyArgsMD (mkMDTy False ty)+ tyArgs = map (PlainTV . mkName) args+ tyArgsMD = map (PlainTV . mkName . (++"_md")) args++-------------------------------------------------------------------------------+-- * Generating Rep/MD Data Declarations++-- | Make the data type declarations for the representation and the metadata of+-- a Pads-defined data type, @'PadsData'@.+mkDataRepMDDecl :: Derivation -> UString -> [LString] -> PadsData -> [QString] -> Q [Dec]+mkDataRepMDDecl derivation name args branches ds = do+ bs' <- mapM (return . mkMDUnion) bs+ imdDecl <- dataD (cxt []) (mkIMDName name) tyArgsMD Nothing bs' [derive []]+ bs'' <- mapM (return . mkRepUnion) bs+ --let ds' = map (conT . mkName . qName) ds+ dataDecl <- dataD (cxt []) (mkRepName name) tyArgs Nothing bs'' [derive ds]+ derivesData <- derivation dataDecl+ derivesImd <- derivation imdDecl+ let mdName = mkMDName name+ --let bT = bangType (mkStrict NotStrict)+ --let mdDeclConstr = normalC mdName $ [bT $ return $ mkTupleT [ConT '' Base_md, imdApp]]+ --mdDecl <- newtypeD (cxt []) mdName tyArgsMD Nothing mdDeclConstr []+ let mdDecl = TySynD (mkMDName name) tyArgsMD (mkTupleT [ConT ''Base_md, imdApp])+ return $ [dataDecl, mdDecl, imdDecl] ++ derivesData ++ derivesImd+ where+ tyArgs = map (PlainTV . mkName) args+ tyArgsMD = map (PlainTV . mkName . (++"_md")) args+ imdApp = foldl AppT (ConT (mkIMDName name)) (map (VarT . mkName . (++"_md")) args)+ bs = case branches of+ PUnion bnchs -> bnchs+ PSwitch exp pbs -> [b | (p,b) <- pbs]++-- | Convert a Pads strictness annotation into the appropriate Haskell+-- strictness annotation in the template haskell Q monad for splicing.+mkStrict :: PadsStrict -> Q Strict+mkStrict NotStrict = bang noSourceUnpackedness noSourceStrictness -- i.e. notStrict+mkStrict IsStrict = bang noSourceUnpackedness sourceStrict -- i.e. isStrict++-- | Make the Haskell data type *constructor* (@'normalC'@ and @'recC'@) for the+-- given fragment of a Pads type (@'BranchInfo'@).+mkRepUnion :: BranchInfo -> ConQ+mkRepUnion (BConstr c args expM) = normalC (mkConstrName c) reps+ where reps = [bangType (mkStrict strict) (return $ mkRepTy ty) | (strict,ty) <- args, hasRep ty]+mkRepUnion (BRecord c fields expM) = recC (mkConstrName c) lreps+ where lreps = [ varBangType+ (mkName l)+ (bangType (mkStrict strict)+ (return $ mkRepTy ty))+ | (Just l,(strict,ty),_,_) <- fields, hasRep ty]++-- | Make the 'Con' metadata constructor definition for an individual branch of+-- a Pads type, which gets used to create the Haskell data type declaration for+-- the metadata of a Pads type.+mkMDUnion :: BranchInfo -> Q Con+mkMDUnion (BConstr c args expM) = normalC (mkConstrIMDName c) mds+ where+ mds = [bangType (mkStrict NotStrict) (return $ mkMDTy False ty) | (_,ty) <- args] --MD , hasRep ty]+mkMDUnion (BRecord c fields expM) = do+ { let lmds = [ do { fn <- genLabMDName "m" lM+ ; varBangType fn (bangType (mkStrict NotStrict) (return $ mkMDTy False ty))+ }+ | (lM,(_,ty),_,_) <- fields+ ]+ ; recC (mkConstrIMDName c) lmds+ }+--MD lmds <- return [(mkFieldMDName l,NotStrict,mkMDTy ty) | (Just l,(_,ty),_) <- fields, hasRep ty]++-- | Make the type context of a data declaration, consisting of the typeclasses+-- instanced by Pads data types.+--derive :: [QString] -> CxtQ+derive :: [QString] -> DerivClauseQ+derive ds = derivClause Nothing $ map (conT . mkName . qName) ds+ ++ [conT $ mkName d | d<-["Show","Eq","Typeable","Data","Ord"], not (d `elem` map last ds)]++-------------------------------------------------------------------------------+-- * Generating Rep/MD Newtype Declarations++-- | Construct the newtype Haskell data declaration from a Pads type defined+-- using the "newtype" keyword.+mkNewRepMDDecl :: Derivation -> UString -> [LString] -> BranchInfo -> [QString] -> Q [Dec]+mkNewRepMDDecl derivation name args branch ds = do+ imdDecl <- newtypeD (cxt []) (mkIMDName name) tyArgsMD Nothing (mkMDUnion branch) [derive []]+ let ds' = map (conT . mkName . qName) ds+ dataDecl <- newtypeD (cxt []) (mkRepName name) tyArgs Nothing (mkRepUnion branch) [derive ds]+ --[derivClause Nothing ds']+ derivesData <- derivation dataDecl+ derivesImd <- derivation imdDecl+ return $ [dataDecl, mdDecl, imdDecl] ++ derivesData ++ derivesImd+ where+ mdDecl = TySynD (mkMDName name) tyArgsMD (mkTupleT [ConT ''Base_md, imdApp])+ tyArgs = map (PlainTV . mkName) args+ tyArgsMD = map (PlainTV . mkName . (++"_md")) args+ imdApp = foldl AppT (ConT (mkIMDName name)) (map (VarT . mkName . (++"_md")) args)++-------------------------------------------------------------------------------+-- * Generating MD Type from Obtain Declarations+-- Design decision not to do this.++-- | Construct the Haskell type synonym declaration for a Pads type declared+-- using the "obtain" keyword.+mkObtainMDDecl :: UString -> [UString] -> PadsTy -> [Dec]+mkObtainMDDecl name args ty+ = [mdType]+ where+ mdType = TySynD (mkMDName name) tyArgsMD (mkMDTy False ty)+ tyArgsMD = map (PlainTV . mkName . (++"_md")) args++-------------------------------------------------------------------------------+-- * Generating Representation Type of a Type Expression++-- | Make the template haskell 'Type' for the given 'PadsTy' pads type, to be+-- used anywhere in generated Haskell code where the representation type is+-- expected.+mkRepTy :: PadsTy -> Type+mkRepTy ty = case ty of+ PPartition pty exp -> mkRepTy pty+ PConstrain pat pty exp -> mkRepTy pty+ PTransform tySrc tyDest exp _ -> mkRepTy tyDest+ PList ty sep term -> ListT `AppT` mkRepTy ty+ PValue exp pty -> mkRepTy pty+ PApp tys expM -> foldl1 AppT [mkRepTy ty | ty <- tys, hasRep ty]+ PTuple tys -> mkRepTuple tys+ PExpression _ -> ConT ''()+ PTycon c -> ConT (mkRepQName c)+ PTyvar v -> VarT (mkName v)++-- | Make the template haskell 'Type' corresponding to a tuple consisting of the+-- given pads types given in list form at compile time '[PadsTy]'.+mkRepTuple :: [PadsTy] -> Type+mkRepTuple tys = case reps of+ [] -> ConT ''()+ [ty] -> ty+ (t:ts) -> mkTupleT reps+ where+ reps = [mkRepTy ty | ty <- tys, hasRep ty]++-------------------------------------------------------------------------------+-- * Generating Meta-Data Representation of Type Expression++-- | Make the template haskell 'Type' corresponding to the externally visible+-- metadata of a given 'PadsTy'. The boolean indicates whether or not Pads type+-- variables 'PTyvar's should be put in a 'Meta' constructor or merely stuffed+-- into a 'VarT' and appended with "_md" postfix. Currently we always do the+-- latter (all calls to 'mkMDTy' give False as the boolean).+mkMDTy :: Bool -> PadsTy -> Type+mkMDTy isMeta ty = case ty of+ PPartition pty exp -> mkMDTy isMeta pty+ PConstrain pat pty exp -> mkMDTy isMeta pty+ PTransform src dest exp _ -> mkMDTy isMeta dest+ PList ty sep term -> mkTupleT [ConT ''Base_md, ListT `AppT` mkMDTy isMeta ty]+ PValue exp pty -> mkMDTy isMeta pty+ PApp tys expM -> foldl1 AppT [mkMDTy isMeta ty | ty <- tys] --MD , hasRep ty]+ PTuple tys -> mkMDTuple isMeta tys+ PExpression _ -> ConT ''Base_md+ PTycon c -> ConT (mkMDQName c)+ PTyvar v -> if isMeta+ then AppT (ConT ''Meta) (VarT $ mkName v)+ else VarT (mkName $ v ++ "_md")++-- | Make the template haskell 'Type' corresponding to a Haskell tuple type+-- consisting of the metadata types for the given Pads types '[PadsTy]'.+mkMDTuple :: Bool -> [PadsTy] -> Type+mkMDTuple isMeta tys = case mds of+ [] -> ConT ''Base_md+ [m] -> mkTupleT [ConT ''Base_md, m]+ (m:ms) -> mkTupleT [ConT ''Base_md, mkTupleT mds]+ where+ mds = [mkMDTy isMeta ty | ty <- tys] --MD , hasRep ty]+++-------------------------------------------------------------------------------+-- * Generating Instance Declarations from Data / New Declarations++-- | Make the following instance and type instance declarations for a Pads data+-- type and new type declaration:+--+-- > [pads| data Foo (Bar1, Bar2, Bar3) = Foo+-- > { i1 :: Bar1+-- > , i2 :: Bar2 i1+-- > , i3 :: Bar3 i2+-- > } |]+--+-- > instance Pads1 (Bar1, Bar2, Bar3) Foo Foo_md where+-- > parsePP1 = foo_parseM+-- > printFL1 = foo_printFL+-- > def1 = foo_def+-- > type instance Meta Foo = Foo_md+-- > type instance PadsArg Foo = (Bar1, Bar2, Bar3)+mkPadsInstance :: UString -> [LString] -> Maybe Type -> [Dec]+mkPadsInstance str args mb@(Nothing)+ = buildInst mb str args (ConT ''Pads1 `AppT` TupleT 0)+mkPadsInstance str args mb@(Just ety)+ = buildInst mb str args (ConT ''Pads1 `AppT` ety)++-- | See 'mkPadsInstance' above.+buildInst mb str args pads =+ [ InstanceD Nothing ctx inst [parsePP_method, printFL_method,def_method]+ , TySynInstD ''Meta $ TySynEqn [ty_name] meta_ty+ , TySynInstD ''PadsArg $ TySynEqn [ty_name] arg_ty+ ]+ where+ arg_ty = case mb of+ Nothing -> TupleT 0+ Just ety -> ety+ mbarg = case mb of+ Nothing -> [TupP []]+ Just _ -> []+ inst = applyT [pads, ty_name, md_ty]+ ty_name = applyT (ConT (mkName str) : map fst argpairs)+ md_ty = applyT (ConT (mkMDName str) : map snd argpairs)+ meta_ty = applyT (ConT (mkMDName str) : metas)+ parsePP_method = FunD 'parsePP1 [Clause mbarg (NormalB (applyE (VarE (mkTyParserName str) : [VarE 'parsePP | a <- args]))) []]+ printFL_method =+ if str == "Entry"+ then FunD 'printFL1 [Clause mbarg (NormalB $ VarE $ mkName "undefined") []]+ else FunD 'printFL1 [Clause mbarg (NormalB (applyE (VarE (mkTyPrinterName str) : [VarE 'printFL | a <- args]))) []]+ def_method = FunD 'def1 [Clause mbarg (NormalB (applyE (VarE (mkTyDefName str) : [VarE 'def | a <- args]))) []]+ argpair n = (VarT (mkName n),VarT (mkName $ n++"_md"))+ meta n = AppT (ConT ''Meta) (VarT $ mkName n)+ argpairs = [argpair a | a <- args]+ metas = map meta args+ argtyvars = concat [[PlainTV (mkName a), PlainTV (mkName (a++"_md"))] | a <- args]++ ctx = [AppT (AppT (ConT ''Pads) r) m | (r,m) <- argpairs]++ padsprinter t t_md = AppT (ConT ''PadsPrinter) $ appT2 (TupleT 2) t t_md++ printer = case mb of+ Nothing -> padsprinter ty_name md_ty+ Just ety -> appT2 ArrowT ety (padsprinter ty_name md_ty)+++-- | Make the following type signatures, applicable for all the forms of a Pads+-- declaration:+--+-- > foo_printFL :: (Bar1, Bar2, Bar3) -> PadsPrinter (Foo, Foo_md)+-- > foo_def :: (Bar1, Bar2, Bar3) -> Foo+--+-- See 'mkPadsInstance' above for the definition of the Pads type "Foo".+mkPadsSignature :: UString -> [LString] -> Maybe Type -> [Dec]+mkPadsSignature str args mb@(Nothing)+ = buildSignature mb str args (ConT ''Pads)+mkPadsSignature str args mb@(Just ety)+ = buildSignature mb str args (ConT ''Pads1 `AppT` ety)++-- | See 'mkPadsSignature' above.+buildSignature mb str args pads =+ if str == "Entry"+ then [def_signature]+ else [printFL_signature,def_signature]+ where+ mbarg = case mb of+ Nothing -> [TupP []]+ Just _ -> []+ inst = applyT [pads, ty_name, md_ty]+ ty_name = applyT (ConT (mkName str) : map (\(x,y,z) -> y) argpairs)+ md_ty = applyT (ConT (mkMDName str) : map (\(x,y,z) -> z) argpairs)+ meta_ty = applyT (ConT (mkMDName str) : metas)+ argpair n = (VarT (mkName $ n++"_arg"),VarT (mkName n),VarT (mkName $ n++"_md"))+ meta n = AppT (ConT ''Meta) (VarT $ mkName n)+ argpairs = [argpair a | a <- args]+ metas = map meta args+ argtyvars = concat [[PlainTV (mkName (a++"_arg")),PlainTV (mkName a), PlainTV (mkName (a++"_md"))] | a <- args]++ printerctx = concat $ [[AppT (ConT ''Data) r, AppT (ConT ''Data) m] | (arg,r,m) <- argpairs]+ defctx = concat $ [[AppT (ConT ''Data) r] | (arg,r,m) <- argpairs]++ padsprinter t t_md = AppT (ConT ''PadsPrinter) $ appT2 (TupleT 2) t t_md+ padsdef t t_md = t++ printer = case mb of+ Nothing -> padsprinter ty_name md_ty+ Just ety -> appT2 ArrowT ety (padsprinter ty_name md_ty)+ def = case mb of+ Nothing -> padsdef ty_name md_ty+ Just ety -> appT2 ArrowT ety (padsdef ty_name md_ty)++ printFL_signature = SigD (mkTyPrinterName str) $ ForallT argtyvars printerctx $ foldr (\a t -> let (a_arg,a_rep,a_md) = argpair a in appT2 ArrowT (padsprinter a_rep a_md) t) printer args+ def_signature = SigD (mkTyDefName str) $ ForallT argtyvars defctx $ foldr (\a t -> let (a_arg,a_rep,a_md) = argpair a in appT2 ArrowT (padsdef a_rep a_md) t) def args++-------------------------------------------------------------------------------+-- * Generating Parser Declaration from Type / Data / New Declarations++-- | Construct the function body and resulting declaration of the "_parseM"+-- function for a given 'PadsTy' type declaration.+genPadsParseM :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]+genPadsParseM name args patM padsTy = do+ let body = genParseTy padsTy+ mkParserFunction name args patM body++-- | 'PadsData' data declaration flavour of the "_parseM" function.+genPadsDataParseM :: UString -> [LString] -> (Maybe Pat) -> PadsData -> Q [Dec]+genPadsDataParseM name args patM padsData = do+ let body = genParseData padsData+ mkParserFunction name args patM body++-- | 'BranchInfo' new type declaration flavour of the "_parseM" function.+genPadsNewParseM :: UString -> [LString] -> (Maybe Pat) -> BranchInfo -> Q [Dec]+genPadsNewParseM name args patM branch = do+ (dec,exp) <- genParseBranchInfo branch+ let body = letE [return dec] (return exp)+ mkParserFunction name args patM body++-- | Pads Obtain declaration flavour of the "_parseM" function.+genPadsObtainParseM :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]+genPadsObtainParseM name args padsTy exp = do+ let body = genParseTy (PTransform padsTy (PTycon [name]) exp Nothing)+ mkParserFunction name args Nothing body++-- | Construct the declaration for a function which monadically parses a Pads+-- type given the body of the function as input.+mkParserFunction :: UString -> [LString] -> Maybe Pat -> Q Exp -> Q [Dec]+mkParserFunction name args patM body+ = sequence $ if name == "Entry" then [sig,fun] else [fun]+ where+ fun = funD parserName [clause parserArgs (normalB body) []]+ sig = sigD parserName [t| PadsParser ($(conT $ mkConstrName name), (Base_md, $(conT $ mkConstrIMDName name))) |]+ parserName = mkTyParserName name+ parserArgs = map (varP . mkVarParserName) args ++ Maybe.maybeToList (return <$> patM)++-------------------------------------------------------------------------------+-- * Generating String-Parser Declaration++-- | Construct the "_parseS" function at compile time such that it makes a call+-- to 'parseStringInput' at runtime.+genPadsParseS :: UString -> [LString] -> Maybe Pat -> Q [Dec]+genPadsParseS name args patM = do+ { body <- [| parseStringInput $(return parserWithArgs) |]+ ; return [ FunD (mkTyParserSName name) [Clause parserArgs (NormalB body) []] ]+ }+ where+ parserWithArgs = foldl1 AppE (VarE parserName : map patToExp parserArgs)+ parserName = mkTyParserName name+ parserArgs = map (VarP . mkVarParserName) args ++ Maybe.maybeToList patM++-------------------------------------------------------------------------------+-- * Generating Parser from Type Expression++-- | This function only ever gets called at compile time in order to construct a+-- template haskell expression to be used somewhere in the body of a "_parseM"+-- function. This expression is the meat of the pads-haskell parsing algorithm+-- and semantics - we use metaprogramming to map the Pads syntax onto+-- expressions which return a tuple consisting of the parsed representation+-- followed by the metadata (with parse errors).+genParseTy :: PadsTy -> Q Exp+genParseTy pty = case pty of+ PConstrain pat ty exp -> genParseConstrain (return pat) ty (return exp)+ PTransform src dest exp _ -> genParseTyTrans src dest (return exp)+ PList ty sep term -> genParseList ty sep term+ PPartition ty exp -> genParsePartition ty exp+ PValue exp ty -> genParseValue exp+ PApp tys argE -> genParseTyApp tys argE+ PTuple tys -> genParseTuple tys+ PExpression exp -> genParseExp exp+ PTycon c -> return $ mkParseTycon c+ PTyvar v -> return $ mkParseTyvar v+++-- | Simply generate a call to the runtime system function 'parseConstraint'+-- where the first argument is a Haskell expression spliced directly into the+-- call to 'parseConstraint' which parses the thing being constrained and the+-- second argument is the (Haskell) predicate function used to constrain the+-- Pads type.+genParseConstrain :: Q Pat -> PadsTy -> Q Exp -> Q Exp+genParseConstrain patQ ty expQ = [| parseConstraint $(genParseTy ty) $pred |]+ where+ pred = lamE [patQ, varP (mkName "md")] expQ+++-- | Simply generate a call to the runtime system function 'parseTransform'+-- where the first argument is the spliced-in-place parser for the "source" Pads+-- type being transformed and the second argument is the (Haskell)+-- transformation function for producing something of the desired destination+-- type. Note that we can ignore the destination 'PadsTy' at compile time in+-- *this* function because the Haskell type checker will type check the result+-- of 'parseTransform' for us.+genParseTyTrans :: PadsTy -> PadsTy -> Q Exp -> Q Exp+genParseTyTrans src dest expQ+ = [| parseTransform $(genParseTy src) (fst $expQ) |]++-- | This compile time function figures out which runtime system support+-- function to generate a call to for parsing a Pads list type based on the+-- given separator Pads type and the desired termination condition 'TermCond'.+genParseList :: PadsTy -> (Maybe PadsTy) -> (Maybe TermCond) -> Q Exp+genParseList ty sep term =+ case (sep,term) of+ (Nothing, Nothing) -> [| parseListNoSepNoTerm $(genParseTy ty) |]+ (Just sep, Nothing) -> [| parseListSepNoTerm $(genParseTy sep) $(genParseTy ty) |]+ (Nothing, Just (LLen lenE)) -> [| parseListNoSepLength $(return lenE) $(genParseTy ty) |]+ (Just sep, Just (LLen lenE)) -> [| parseListSepLength $(genParseTy sep) $(return lenE) $(genParseTy ty) |]+ (Nothing, Just (LTerm term))-> [| parseListNoSepTerm $(genParseTy term) $(genParseTy ty) |]+ (Just sep, Just (LTerm term))-> [| parseListSepTerm $(genParseTy sep) $(genParseTy term) $(genParseTy ty) |]+++-- | Simply generate a call to the runtime system function 'parsePartition'+-- where the first argument is an expression for parsing the 'PadsTy' pads type+-- we're partitioning on and the second argument is the Haskell expression given+-- in the Pads syntactic form specifying the record discipline with which to+-- partition things. For example the following code:+--+-- > type Foo = (partition [Bar] using none)+--+-- declares a type Foo which is a list of Bars where Bars are separated by+-- nothing.+genParsePartition :: PadsTy -> Exp -> Q Exp+genParsePartition ty disc = [| parsePartition $(genParseTy ty) $(return disc) |]++-- | This compile time function generates code which wraps a Pads Value type's+-- Haskell expression in the appropriate type to be returned for use in the pads+-- parsing monad, namely of type 'PadsParser (rep, md)' where rep and md are the+-- representation and metadata type variables.+genParseValue :: Exp -> Q Exp+genParseValue exp = [| return ($(return exp), cleanBasePD) |]+--genParseValue exp = return $ AppE (VarE 'return) (TupE [exp,VarE 'cleanBasePD])++-- | Construct the sequentially-defined parser for a Pads tuple type.+genParseTuple :: [PadsTy] -> Q Exp+genParseTuple [] = [| return ((), cleanBasePD) |]+genParseTuple tys = do+ f_rep_name <- newName "f_rep"+ f_md_name <- newName "f_md"+ let f_rep = buildF_rep f_rep_name vars_frep+ f_rep_sig = buildF_rep_sig f_rep_name sigs_frep+ f_md = buildF_md f_md_name vars_fmd+ --f_md_sig <- buildF_md_sig f_md_name tys+ body <- foldl parseNext [| return ($(dyn "f_rep"),$(dyn "f_md")) |] tys+ return (LetE [f_rep_sig,f_rep {-,f_md_sig-},f_md] body)+ where+ vars_frep = [v | (v,t) <- zip vars_fmd tys, hasRep t]+ sigs_frep = [t | t <- tys, hasRep t]+ vars_fmd = [ mkName ("x"++show n) | n <- [1 .. length tys]]++-- | Glom the generated parser for the given 'PadsTy' onto the given parser+-- using the '=@=' and '=@' runtime system operators.+parseNext :: Q Exp -> PadsTy -> Q Exp+parseNext prog t+ | hasRep t = [| $prog =@= $(genParseTy t) |]+ | otherwise = [| $prog =@ $(genParseTy t) |]++-- | Construct the "f_rep" let-bound function inside of a Pads tuple type for+-- uncurrying the result of parsing the tuple sequentially at runtime. The+-- "f_rep" function generated by *this* function gets passed into the '=@=' and+-- '=@' runtime system operators which call f_rep on the result of parsing each+-- of the members of the tuple.+buildF_rep :: Name -> [Name] -> Dec+buildF_rep name vars_frep+ = FunD name [Clause+ (map VarP vars_frep) (NormalB (TupE (map VarE vars_frep))) [] ]++isVarT (VarT _) = True+isVarT _ = False++findPTyVars :: [PadsTy] -> [Name]+findPTyVars ptys = let++ varTs' :: PadsTy -> [String]+ varTs' (PTyvar s) = [s]+ varTs' t = varTs t++ varTs (PConstrain _ t _) = varTs' t+ varTs (PTransform t1 t2 _ _) = varTs' t1 ++ varTs' t2+ varTs (PList t1 (Just t2) _) = varTs' t1 ++ varTs' t2+ varTs (PList t1 Nothing _) = varTs' t1+ varTs (PPartition t _) = varTs' t+ varTs (PValue _ t) = varTs' t+ varTs (PApp ts _) = concatMap varTs ts+ varTs _ = []++ in List.nub $ concatMap (map mkName . varTs) ptys++buildF_md_sig :: Name -> [PadsTy] -> Q Dec+buildF_md_sig name ptys = do+ let tys = map (mkMDTy False) ptys+ mdRet = foldl AppT (TupleT $ length tys) tys+ retTy <- [t| (Base_md, $(return mdRet)) |]+ let sigTy = foldr1 (appT2 ArrowT) (tys ++ [retTy])+ ptyVarNames = findPTyVars ptys --filter isVarT tys+ varTTys = map VarT ptyVarNames+ varTNames = map PlainTV ptyVarNames+ sigT' = ForallT varTNames (map (AppT (ConT ''PadsMD)) varTTys+ ++ map (AppT (ConT ''Data)) varTTys) sigTy+ do D.traceM $ "buildF_md_sig] " ++ show name ++ " \n " ++ show varTNames ++ " \n "+ ++ show tys ++ " \n " ++ show ptys+ return (case tys of+ [] -> SigD name $ TupleT 0+ (t:[]) -> SigD name $ appT2 ArrowT t t+ _ -> SigD name $ sigT')++-- | Same as 'buildF_rep' above but for the metadata instead of the parse+-- representation. In this case we need to pull off just the 'Base_md' from the+-- metadata resulting from whatever the parser returned to us for each of the+-- tuple results using the 'get_md_header' type class function provided by the+-- runtime system.+buildF_md :: Name -> [Name] -> Dec+buildF_md f_md_name vars_fmd+ = FunD f_md_name [Clause (map VarP vars_fmd) (NormalB body) []]+ where+ mdHeaders = [ VarE 'get_md_header `AppE` VarE xi | xi <- vars_fmd ]+ body = TupE [mkMergeBaseMDs mdHeaders, TupE (map VarE vars_fmd)]++buildF_rep_sig :: Name -> [PadsTy] -> Dec+buildF_rep_sig name ptys = let+ tys = map mkRepTy ptys+ retTy = foldl AppT (TupleT $ length tys) tys+ sigTy = foldr1 (appT2 ArrowT) (tys ++ [retTy])+ in (case tys of+ [] -> SigD name $ TupleT 0+ (t:[]) -> SigD name $ appT2 ArrowT t t+ _ -> SigD name $ sigTy)++-- | Generate a call to 'mergeBaseMDs'+mkMergeBaseMDs :: [Exp] -> Exp+mkMergeBaseMDs [e] = e+mkMergeBaseMDs es = VarE 'mergeBaseMDs `AppE` ListE es++-- | Construct a call to the 'litParse' runtime system type class function so+-- that we can parse a literal (Haskell) expression. The type of the expression+-- provided as a Haskell expression must be Literally Parseable ('LitParse' type+-- class), otherwise the code generated by *this* compile time function produces+-- a type error.+genParseExp :: Exp -> Q Exp+genParseExp exp = [| litParse $(return exp) |]++-- | Generate the parser for a Pads type application.+genParseTyApp :: [PadsTy] -> Maybe Exp -> Q Exp+genParseTyApp tys expM = do+ fs <- mapM genParseTy tys+ return (foldl1 AppE (fs ++ Maybe.maybeToList expM))++-- | Make the parser for a Pads type constructor - just return it as a Haskell+-- variable expression.+mkParseTycon :: QString -> Exp+mkParseTycon ["EOF"] = VarE 'eof_parseM+mkParseTycon ["EOR"] = VarE 'eor_parseM+mkParseTycon c = VarE (mkTyParserQName c)++-- | Make the parser for a Pads type variable - just return it as a Haskell+-- variable expression.+mkParseTyvar :: String -> Exp+mkParseTyvar v = VarE (mkVarParserName v) -- should gensym these, but probably ok+++-- * Generating Parsers from Union/Switch Expressions++-- | A data declaration in pads is either a union or a switch expression -+-- generate the template haskell for parsing them.+genParseData :: PadsData -> Q Exp+genParseData (PUnion bs) = genParseUnion bs+genParseData (PSwitch exp pbs) = genParseSwitch exp pbs++-- | Generate the template haskell for parsing a Pads union expression. Namely+-- generate the metadata constructors for each of the branches of the union and+-- stuff them into let-bound functions so that nested parsers have them in+-- scope. Then generate a call to the runtime system function 'choiceP' for+-- choosing among the different parsers.+genParseUnion :: [BranchInfo] -> Q Exp+genParseUnion bs = do+ { (decs,bodies) <- fmap unzip $ mapM genParseBranchInfo bs+ ; let body = case bodies of+ [b] -> b+ bs -> (VarE 'choiceP) `AppE` (ListE bs)+ ; return (LetE decs body)+ }++-- | Generate the template haskell case expression from a Pads switch type. This+-- is almost entirely just matching the syntax of a Pads case onto the syntax of+-- a Haskell case expression. Semantically the case just figures out which+-- parser needs to be run by pattern matching on something already parsed from+-- the input.+genParseSwitch :: Exp -> [(Pat,BranchInfo)] -> Q Exp+genParseSwitch exp pbs = do+ let (ps,bs) = unzip pbs+ (decs,bodies) <- fmap unzip $ mapM genParseBranchInfo bs+ let body = CaseE exp [Match p (NormalB b) [] | (p,b) <- zip ps bodies]+ return (LetE decs body)++-- | Generate the parser for an individual branch of a Pads new type, Pads+-- union, or Pads switch.+genParseBranchInfo :: BranchInfo -> Q (Dec,Exp)+genParseBranchInfo (BRecord c fields pred) = genParseRecord c fields pred+genParseBranchInfo (BConstr c args pred) = do+ { body <- foldl parseNext [| return ($(conE (mkConstrName c)),$(varE (mkfnMDName c))) |] tys+ ; return (con_md, body)+ }+ where+ tys = [ty | (strict,ty) <- args]+ con_md = buildConstr_md (mkfnMDName c) (ConE (mkConstrIMDName c)) tys++-- | Build the constructor function for tupling together the metadata results of+-- parsing a bunch of Pads types.+buildConstr_md :: Name -> Exp -> [PadsTy] -> Dec+buildConstr_md fnMD conMD tys+ = FunD fnMD [Clause (map VarP vars_fmd) (NormalB body) []]+ where+ vars_fmd = [ mkName ("x"++show n) | n <- [1 .. length tys]]+ mdHeaders = [ VarE 'get_md_header `AppE` VarE xi | xi <- vars_fmd ]+ body = TupE [mkMergeBaseMDs mdHeaders, applyE (conMD : map VarE vars_conmd)]+ vars_conmd = vars_fmd --MD [v | (v,t) <- zip vars_fmd tys, hasRep t]++-------------------------------------------------------------------------------+-- * Generating Parsers from Record Expressions++-- | Generate the template haskell code for parsing a Pads record.+genParseRecord :: UString -> [FieldInfo] -> (Maybe Exp) -> Q (Dec,Exp)+genParseRecord c fields pred = do+ c_md <- newName (strToLower c)+ let con_md = buildConstr_md c_md (ConE (mkConstrIMDName c))+ [ty | (_,(_,ty),_,_) <- fields]+ labMDs <- sequence [genLabMDName "x" l | (l,(_,_),_,_) <- fields]+ let fnMDLabs = applyE $ map VarE (c_md : labMDs)+ doStmts <- sequence $ [genParseField f xn | (f,xn) <- zip fields labMDs]+ let labs = [mkName lab | (Just lab,(_,ty),_,_) <- fields, hasRep ty]+ let conLabs = applyE (ConE (mkConstrName c) : map VarE labs)+ returnStmt <- [| return ($(return conLabs),$(return fnMDLabs)) |]+ return (con_md, DoE (concat doStmts ++ [NoBindS returnStmt]))++-- | Generate the name (label?) for the metadata of a field in a record.+genLabMDName :: String -> Maybe String -> Q Name+genLabMDName s (Just lab) = return (mkFieldMDName lab)+genLabMDName s Nothing = liftM mangleName (newName s)++-- | Generate the parser for a field of a Pads record.+genParseField :: FieldInfo -> Name -> Q [Stmt]+genParseField (labM, (strict, ty), expM,_) xn = do+ let parseTy = (case expM of+ Nothing -> genParseTy ty+ Just exp -> genParseRecConstrain labP (varP xn) ty (return exp))+ sequence $+ [ bindS (tupP [labP, varP xn]) parseTy+ ]+ where+ labP = case labM of+ Just lab -> varP (mkName lab)+ Nothing -> wildP++-- | Generate the parser for a constrained field on a record.+genParseRecConstrain :: Q Pat -> Q Pat -> PadsTy -> Q Exp -> Q Exp+genParseRecConstrain labP xnP ty exp = [| parseConstraint $(genParseTy ty) $pred |]+ where+ pred = lamE [labP, xnP] exp+++-------------------------------------------------------------------------------+-- * Generating generation functions++-- * Generating Generator Declaration from Type / Data / New declarations++-- These functions largely mirror the structure of the above "ParseM"+-- functions, differing in the sort of function they output but sharing in+-- common how they construct said function.++-- | PadsDeclType generator declaration+genPadsGenM :: UString -> [LString] -> Maybe Pat -> PadsTy -> Maybe Exp -> Q [Dec]+genPadsGenM name args patM padsTy genM = do+ let body = case genM of Just gen -> return gen+ Nothing -> genGenTy padsTy+ mkGeneratorFunction name args patM body++-- | PadsDeclData generator declaration+genPadsDataGenM :: UString -> [LString] -> (Maybe Pat) -> PadsData -> Q [Dec]+genPadsDataGenM name args patM padsData = do+ let body = genGenData padsData+ mkGeneratorFunction name args patM body++-- | PadsDeclNew generator declaration+genPadsNewGenM :: UString -> [LString] -> (Maybe Pat) -> BranchInfo -> Q [Dec]+genPadsNewGenM name args patM branch = do+ exp <- genGenBranchInfo branch+ mkGeneratorFunction name args patM (return exp)++-- | PadsDeclObtain generator declaration - if the user provided a generator,+-- it will be included. If not, the type will lack a generator. If the user+-- includes a function conforming to the naming convention of a generator, i.e.+-- "name_genM" for a PadsTy called "Name," it is redundant (and in fact+-- erroneous) to include "generator name_genM," as this will result in an+-- attempted redefinition of name_genM as itself.+genPadsObtainGenM :: UString -> [LString] -> PadsTy -> Exp -> Maybe Exp -> Q [Dec]+genPadsObtainGenM name _ _ _ (Just gen) = mkGeneratorFunction name [] Nothing (return gen)+genPadsObtainGenM _ _ _ _ Nothing = return []++-- | Create the actual generator function declaration for any PadsDecl flavor+mkGeneratorFunction :: UString -> [LString] -> Maybe Pat -> Q Exp -> Q [Dec]+mkGeneratorFunction name args patM body+ = sequence [fun]+ where+ fun = funD generatorName [clause generatorArgs (normalB body) []]+ generatorName = mkTyGeneratorName name+ generatorArgs = map (varP . mkVarGeneratorName) args ++ Maybe.maybeToList (return <$> patM)+++-- * Generating Generators from Union/Switch Expressions++-- | Generate the generators for Pads data declarations.+genGenData :: PadsData -> Q Exp+genGenData (PUnion bs) = genGenUnion bs+genGenData (PSwitch exp pbs) = do+ let matches = [match (return p) (normalB $ genGenBranchInfo b) [] | (p,b) <- pbs]+ caseE (return exp) matches++-- | Creates a runtime function which picks at random from the generators for+-- each branch of the union, all of which are created here.+genGenUnion :: [BranchInfo] -> Q Exp+genGenUnion bs =+ case bs of+ [b] -> genGenBranchInfo b+ bs -> do+ let bs' = map genGenBranchInfo bs+ index <- newName "index"+ dos <- newName "dos"+ bindList <- letS [valD (varP dos) (normalB (listE bs')) []]+ bindIndex <- bindS (varP index) [| randNumBound (length $(varE dos) - 1) |]+ indexList <- noBindS [| $(varE dos) !! $(varE index) |]+ return $ DoE [bindList,bindIndex,indexList]++-- | Dispatch to genGenRecord or genGenConstr+genGenBranchInfo :: BranchInfo -> Q Exp+genGenBranchInfo (BRecord c fields pred) = genGenRecord c fields pred+genGenBranchInfo (BConstr c args pred) = genGenConstr c args pred++-- | Generate the template Haskell code for generating a Pads record.+genGenRecord :: UString -> [FieldInfo] -> (Maybe Exp) -> Q Exp+genGenRecord c fields pred = do+ doStmts <- sequence $ map genGenField fields+ let labels = map mkName $ Maybe.catMaybes $ [label | (label,(_,ty),_,_) <- fields, hasRep ty]+ let conLabs = applyE (ConE (mkConstrName c) : map VarE labels)+ let a = (varT . mkName) "a"+ returnStmt <- [| (return :: $a -> PadsGen st $a) ($(return conLabs)) |]+ return $ DoE (concat doStmts ++ [NoBindS returnStmt])++-- | Generate the generator for a field of a Pads record; each one becomes a+-- binding statement in a haskell do-expression.+genGenField :: FieldInfo -> Q [Stmt]+genGenField (labM, (strict, ty), expM, genM) = do+ let labP = case labM of Nothing -> wildP+ Just lab -> varP $ mkName lab+ let genTy = case expM of Nothing -> case genM of Just gen -> return gen; _ -> genGenTy ty+ Just exp -> [| error "genGenField: parameterization via expression unsupported" |]+ sequence [bindS labP genTy]++-- | Generate the generator for a PADS data constructor (BConstr format of+-- BranchInfo).+genGenConstr :: String -> [ConstrArg] -> Maybe Exp -> Q Exp+genGenConstr c args pred = do+ let tys = [ty | (_,ty) <- args]+ let tys' = map genGenTy (filter hasRep tys)+ names <- sequence [newName "x" | ty <- tys']+ binds <- sequence [bindS (varP n) ty | (n,ty) <- zip names tys']+ let constructor = (conE . mkName) c+ let toreturn = foldl1 appE (constructor : (map varE names))+ let a = (varT . mkName) "a"+ ret <- noBindS [| (return :: $a -> PadsGen st $a) $toreturn |]+ return $ DoE (binds ++ [ret])++-- * Generating Generator from Type Expression++-- | Driver function for creating generators. Provided a PadsTy, it will return+-- a generator customized to work with that particular type.+genGenTy :: PadsTy -> Q Exp+genGenTy pty = case pty of+ PConstrain pat ty exp -> genGenConstrain pat ty exp+ PTransform src dest exp genM -> genGenTransform src dest exp genM+ PList ty sep term -> genGenList ty sep term+ PPartition ty exp -> genGenTy ty+ PValue exp ty -> genGenValue exp+ PApp tys argE -> genGenTyApp tys argE+ PTuple tys -> genGenTuple tys+ PExpression exp -> [| return $(return exp) |]+ PTycon c -> mkGenTycon c+ PTyvar v -> mkGenTyvar v++-- | Generate code that uses the runtime function 'randWithConstraint' to+-- generate random data until one satisfies the constraint. If a predicate+-- requires that the variable in question be exactly equal to a value,+-- randWithConstraint is bypassed and that value is assigned directly.+--+-- e.g. @constrain tcpDstPort :: Bits16 16 <| tcpDstPort == 22 |>@ will avoid+-- creating new 16-bit values until one happens to be equal to 22, and will+-- instead assign the literal 22 to tcpDstPort.+genGenConstrain :: Pat -> PadsTy -> Exp -> Q Exp+genGenConstrain pat pty e = let+ var = fromVarP pat+ patQ = return pat+ eQ = return e+ in case e of+ (UInfixE y eq z)+ | simpleEquality var y eq z -> [| return $(return z) |]+ | simpleEquality var z eq y -> [| return $(return y) |]+ _ -> [| randWithConstraint $(genGenTy pty) $(lamE [patQ] eQ) |]++ where+ fromVarP :: Pat -> Exp+ fromVarP (VarP x) = VarE x++ simpleEquality :: Exp -> Exp -> Exp -> Exp -> Bool+ simpleEquality var y eq z = (y == var && eq == (VarE . mkName) "==")++-- | If an optional generator is included in the quasiquoted PADS description,+-- simply provide it. If not, fail with a (hopefully) helpful error message.+genGenTransform :: PadsTy -> PadsTy -> Exp -> Maybe Exp -> Q Exp+genGenTransform src dest exp genM = case genM of+ Just g -> return g+ Nothing -> [| (return $+ error $ "genGenTy: PTransform unimplemented. You likely arrived "+ ++ "at this error by having an \"obtain\" declaration/expression "+ ++ "in your description with no provided generator. If "+ ++ "so, you can provide your own generation function f "+ ++ "by appending \" generator f\" to it.") :: PadsGen st a |]++-- | Generate a list representing a Pads list type by generating a call to+-- the runtime function 'randList'. We ignore the separator and LTerm+-- termination condition here and incorporate them during serialization, but the+-- LLen termination condition is respected at this stage.+genGenList :: PadsTy -> (Maybe PadsTy) -> (Maybe TermCond) -> Q Exp+genGenList pty _ (Just (LLen e)) = let+ gen = genGenTy pty+ in [| randList $gen (Just $(return e)) |]+genGenList pty _ _ = let+ gen = genGenTy pty+ in [| randList $gen Nothing |]+++-- | All variables on which a PValue statement depends will be in scope at this+-- point, so the expression can be returned and evaluated at runtime.+genGenValue :: Exp -> Q Exp+genGenValue exp = [| return $(return exp) |]++-- | Generate the generator for a Pads tuple+genGenTuple :: [PadsTy] -> Q Exp+genGenTuple [] = [| return () |]+genGenTuple tys = do+ tys' <- mapM genGenTy (filter hasRep tys)+ names <- sequence [newName "x" | t <- tys']+ let stmts = [BindS (VarP n) t | (n,t) <- zip names tys']+ ret <- noBindS [| return $(tupE (map varE names)) |]+ return $ DoE (stmts ++ [ret])++-- | Generate the generator for a Pads type application.+genGenTyApp :: [PadsTy] -> Maybe Exp -> Q Exp+genGenTyApp tys expM = do+ tys' <- mapM genGenTy tys+ return (foldl1 AppE (tys' ++ Maybe.maybeToList expM))++-- | Basically same as mkParseTycon, but the name that results is different.+mkGenTycon :: QString -> Q Exp+mkGenTycon ["EOF"] = varE 'eOF_genM+mkGenTycon ["EOR"] = varE 'eOR_genM+mkGenTycon c = (varE . mkTyGeneratorQName) c++-- | Basically same as mkParseTyvar, but the name that results is different.+mkGenTyvar :: String -> Q Exp+mkGenTyvar v = varE (mkVarGeneratorName v)+++-------------------------------------------------------------------------------+-- * Generating Serialization Functions++-- | Create the serializer for a PadsDeclType declaration+genPadsSerialize :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]+genPadsSerialize name args patM padsTy = do+ body <- genSerializeTy padsTy ((Just . VarE . mkName) "rep")+ return [mkSerializerFunction name args patM body]++-- | Create the serializer for a PadsDeclData declaration+genPadsDataSerialize :: UString -> [LString] -> Maybe Pat -> PadsData -> Q [Dec]+genPadsDataSerialize name args patM padsData = do+ body <- genSerializeData padsData ((Just . VarE . mkName) "rep")+ return [mkSerializerFunction name args patM body]++-- | Create the serializer for a PadsDeclNew declaration+genPadsNewSerialize :: UString -> [LString] -> Maybe Pat -> BranchInfo -> Q [Dec]+genPadsNewSerialize name args pat branch = do+ exp <- genSerializeUnion [branch] ((Just . VarE . mkName) "rep")+ return [mkSerializerFunction name args pat exp]++-- | Create the serializer for a PadsDeclObtain declaration+genPadsObtainSerialize :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]+genPadsObtainSerialize name args padsTy exp = do+ let trans = PTransform padsTy (PTycon [name]) exp Nothing+ e <- genSerializeTy trans ((Just . VarE . mkName) "rep")+ return [mkSerializerFunction name args Nothing e]++-- | Create the function declaration for a serialization function+mkSerializerFunction :: UString -> [LString] -> Maybe Pat -> Exp -> Dec+mkSerializerFunction name args patM body =+ FunD serializerName [Clause (serializerArgs ++ [(VarP . mkName) "rep"]) (NormalB body) []]+ where+ serializerName = mkTySerializerName name+ serializerArgs = map (VarP . mkTySerializerVarName) args ++ Maybe.maybeToList patM++-- | Create the serializer for a given form of PadsData+genSerializeData :: PadsData -> Maybe Exp -> Q Exp+genSerializeData (PUnion bs) rep = genSerializeUnion bs rep+genSerializeData (PSwitch exp pbs) rep = genSerializeSwitch exp pbs rep++-- | Create the serializer for a PUnion type of data constructor+genSerializeUnion :: [BranchInfo] -> Maybe Exp -> Q Exp+genSerializeUnion bs (Just rep) = do+ matches <- concat <$> mapM genSerializeBranchInfo bs+ return $ CaseE rep matches+genSerializeUnion bs Nothing = error "genSerializeUnion: expected rep"++-- | At the serialization stage, a PSwitch is simply a sugared PUnion; treat it+-- accordingly here.+genSerializeSwitch :: Exp -> [(Pat,BranchInfo)] -> Maybe Exp -> Q Exp+genSerializeSwitch _ pbs r = genSerializeUnion (map snd pbs) r++-- | Dispatch to the appropriate function based on the type of BranchInfo.+genSerializeBranchInfo :: BranchInfo -> Q [Match]+genSerializeBranchInfo (BRecord c fields predM) = genSerializeRecord c fields predM+genSerializeBranchInfo (BConstr c args predM) = genSerializeConstr c args predM++-- | Serialization of records is accomplished with a case statement at runtime+-- to bring all names of variables into scope+genSerializeRecord :: UString -> [FieldInfo] -> Maybe Exp -> Q [Match]+genSerializeRecord recName fields predM = do+ let (namesM, tys) = unzip (map (\(n,(_,t),_,_) -> (n,t)) fields)+ let serializers = map (\(n,t) -> genSerializeTy t ((VarE . mkName) <$> n)) (zip namesM tys)+ let serialized = [app s n t | (s,n,t) <- zip3 serializers namesM tys]+ casePat <- conP (mkName recName) (map (varP . mkName) (Maybe.catMaybes namesM))+ caseBody <- normalB [| cConcat $(listE serialized) |]+ return [Match casePat caseBody []]+ where+ app :: Q Exp -> Maybe String -> PadsTy -> Q Exp+ app s (Just n) t = s+ app s Nothing t = if hasRep t then s `appE` (genDefTy t) else s++-- | Serialization of branch constructors is somewhat similar to that of+-- records, but differs in the lack of named variables. Simply create TH+-- newNames for each relevant variable or constant.+genSerializeConstr :: String -> [ConstrArg] -> Maybe Exp -> Q [Match]+genSerializeConstr name args predM = do+ let tys = [ty | (_,ty) <- args]+ let tys' = map (flip genSerializeTy Nothing) tys+ names <- sequence [newName "x" | ty <- tys]+ let params = [varE n | n <- names]+ let apps = listE [if hasRep t then s `appE` p else s | (s,p,t) <- zip3 tys' params tys]+ matchPat <- conP (mkName name) [varP n | (n, t) <- zip names tys, hasRep t]+ matchBody <- normalB $ [| cConcat $apps |]+ return [Match matchPat matchBody []]++-- | Driver function to serialize PadsTys, dispatches to the appropriate helper.+-- The "Maybe Exp" parameter informs a function whether or not it needs to+-- apply the serializer it creates to the variable standing for the Haskell data+-- representation - usually "rep" in generated code.+genSerializeTy :: PadsTy -> (Maybe Exp) -> Q Exp+genSerializeTy (PConstrain pat ty exp) r = genSerializeConstrain pat ty exp r+genSerializeTy (PTransform src dest exp _) r = genSerializeTransform src dest exp r+genSerializeTy (PList ty sepM termM) r = genSerializeList ty sepM termM r+genSerializeTy (PPartition ty exp) r = genSerializePartition ty exp r+genSerializeTy (PValue exp ty) r = genSerializeValue exp ty r+genSerializeTy (PApp tys expM) r = genSerializeApp tys expM r+genSerializeTy (PTuple tys) r = genSerializeTuple tys r+genSerializeTy (PExpression exp) r = genSerializeExp exp r+genSerializeTy (PTycon c) r = genSerializeTycon c r+genSerializeTy (PTyvar v) r = genSerializeTyvar v r++-- | At the serialization stage, already existing data cannot be constrained,+-- unlike in the generation stage. Here we merely pass the type back into+-- genSerializeTy to obtain its serializer.+genSerializeConstrain :: Pat -> PadsTy -> Exp -> (Maybe Exp) -> Q Exp+genSerializeConstrain _ ty _ r = genSerializeTy ty r++-- | Serialization of a PTransform PadsTy requires only a thin skin atop the+-- functions provided for converting between types.+genSerializeTransform :: PadsTy -> PadsTy -> Exp -> (Maybe Exp) -> Q Exp+genSerializeTransform src dest (TupE [srcToDest,destToSrc]) r = do+ let srcSerializer = genSerializeTy src Nothing+ let destToSrc' = [| \x -> $(return destToSrc) (x, undefined) |]+ let serializer = [| $srcSerializer . fst . $destToSrc' |]+ case r of+ Just rep -> [| $serializer $(return rep) |]+ Nothing -> [| $serializer |]++-- | Create a serializer for a PList, which will intersperse separators and+-- incorporate terminating conditions as necessary.+genSerializeList :: PadsTy -> (Maybe PadsTy) -> (Maybe TermCond) -> (Maybe Exp) -> Q Exp+genSerializeList ty sepM termM r = do+ let s = genSerializeTy ty Nothing+ cs <- newName "cs"+ cs' <- newName "cs_sep"+ cs'' <- newName "cs_sep_term"+ dec1 <- [d| $(varP cs) = map $s $(dyn "rep") |]+ dec2 <- case sepM of+ Nothing -> [d| $(varP cs') = $(varE cs) |]+ Just s -> let+ def = genDefTy s+ def_s = genSerializeTy s Nothing+ app = if hasRep s then def_s `appE` def else def_s+ in [d| $(varP cs') = intersperse $app $(varE cs) |]+ dec3 <- case termM of+ Nothing -> [d| $(varP cs'') = cConcat $(varE cs') |]+ Just (LLen e) -> case sepM of+ Nothing ->+ [d| $(varP cs'') = cConcat $ take $(return e) $(varE cs') |]+ Just _ ->+ [d| $(varP cs'') = cConcat $ take ($(return e)*2 - 1) $(varE cs') |]+ Just (LTerm t) -> let+ def = genDefTy t+ def_s = genSerializeTy t Nothing+ app = if hasRep t then def_s `appE` def else def_s+ in [d| $(varP cs'') = cConcat $(varE cs') `cAppend` $app |]+ let lamArgs = [(VarP . mkName) "rep"]+ let letDecs = dec1 ++ dec2 ++ dec3+ return $+ case r of Just rep -> (LamE lamArgs $ LetE letDecs (VarE cs'')) `AppE` rep+ Nothing -> (LamE lamArgs $ LetE letDecs (VarE cs''))++-- | Create a serializer for a PPartition type. We can ignore "bytes X" and+-- "none" disciplines, as such disciplines are only relevant to parsing, and+-- simply serialize the underlying type. As for "newline" and "windows"+-- disciplines, instead of figure out where to place the relevant characters,+-- provide a helpful error.+genSerializePartition :: PadsTy -> Exp -> (Maybe Exp) -> Q Exp+genSerializePartition ty exp r+ | exp == (VarE (Name (OccName "newline") NameS))+ = [| error "genSerializePartition: unimplemented: newline discipline" |]+ | exp == (VarE (Name (OccName "windows") NameS))+ = [| error "genSerializePartition: unimplemented: windows discipline" |]+ | otherwise = genSerializeTy ty r++-- | PValues are stored in a parse result but do not appear in the original+-- data. Relying on all serializations being concatenated, where each+-- serialization is a CList, we can provide an "empty" serialization for a+-- PValue with (const) id.+genSerializeValue :: Exp -> PadsTy -> (Maybe Exp) -> Q Exp+genSerializeValue _ _ (Just rep) = [| id |]+genSerializeValue _ _ Nothing = [| const id |]++-- | A PADS application of types is translated directly to a Template Haskell+-- application (AppE).+genSerializeApp :: [PadsTy] -> (Maybe Exp) -> (Maybe Exp) -> Q Exp+genSerializeApp tys expM r = do+ serializers <- mapM (flip genSerializeTy Nothing) tys+ return (foldl1 AppE (serializers ++ Maybe.maybeToList expM ++ Maybe.maybeToList r))++-- | In the runtime function, a case statement is deployed to ensure the input+-- has the correct tuple format, then a serializer for each element of the tuple+-- is bound in a let statement, with their results concatenated to create the+-- function's overall result.+genSerializeTuple :: [PadsTy] -> (Maybe Exp) -> Q Exp+genSerializeTuple tys r = do+ let serializers = map (flip genSerializeTy Nothing) tys+ letnames <- sequence [newName "k" | s <- serializers] -- newName "x" results in a capturable name?+ casenames <- sequence [newName "y" | s <- serializers]+ let letdecs = map mkDec (zip3 letnames casenames (zip tys serializers))+ let letbody = [| cConcat $(listE $ map varE letnames) |]+ let casebody = normalB $ letE letdecs letbody+ let casenames' = [cn | (cn,ty) <- zip casenames tys, hasRep ty]+ case r+ of Just rep -> let+ lamArgs = [(varP . mkName) "rep"]+ matches = [match (tupP [varP cn | cn <- casenames']) casebody []]+ in (lamE lamArgs (caseE (dyn "rep") matches)) `appE` (return rep)+ Nothing -> let+ lamArgs = [(varP . mkName) "rep"]+ matches = [match (tupP [varP cn | cn <- casenames']) casebody []]+ in (lamE lamArgs (caseE (dyn "rep") matches))+ where+ mkDec :: (Name, Name, (PadsTy, Q Exp)) -> Q Dec+ mkDec (ln, cn, (t, t')) = if hasRep t+ then valD (varP ln) (normalB (appE t' (varE cn))) []+ else valD (varP ln) (normalB t' ) []+++-- | The runtime function exp_serialize can be called on literal numbers,+-- characters, and strings, and will serialize them appropriately.+genSerializeExp :: Exp -> (Maybe Exp) -> Q Exp+genSerializeExp exp _ = [| exp_serialize $(return exp) |] --error "genSerializeExp: unexpected representation" --appE [| exp_serialize $(return exp) |] (return rep)++-- | A PTycon is represented according to mkTySerializerName, where the+-- resultant name will be an in-scope runtime serializer.+genSerializeTycon :: QString -> (Maybe Exp) -> Q Exp+genSerializeTycon c r = case r of+ (Just rep) -> return $ AppE ((VarE . mkTySerializerQName) c) rep+ Nothing -> return $ (VarE . mkTySerializerQName) c++-- | A PTyvar is represented according to mkTySerializerVarName, where the+-- resultant name will stand for a serializer the user must provide.+genSerializeTyvar :: String -> (Maybe Exp) -> Q Exp+genSerializeTyvar s (Just rep) = return $ (VarE $ mkTySerializerVarName s) `AppE` rep+genSerializeTyvar s Nothing = return $ (VarE $ mkTySerializerVarName s)++-------------------------------------------------------------------------------+-- Generating Printing Function from a Declaration++-- | Generate the lazy "function list" printer for a given 'PadsTy' Pads type as+-- parsed using Pads' plain-type syntactic form..+genPadsPrintFL :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]+genPadsPrintFL name args patM padsTy = do+ let rm = [mkName "rep", mkName "md"]+ body <- genPrintTy padsTy $ Just $ TupE (map VarE rm)+ return [mkPrinterFunction name args rm patM body]++-- | Generate the lazy function list printer for the Pads data-type syntactic+-- form.+genPadsDataPrintFL :: UString -> [LString] -> Maybe Pat -> PadsData -> Q [Dec]+genPadsDataPrintFL name args patM padsData = do+ let rm = [mkName "rep", mkName "md"]+ body <- genPrintData padsData $ Just $ TupE (map VarE rm)+ return [mkPrinterFunction name args rm patM body]++-- | Generate the lazy function list printer for the Pads newtype syntactic form.+genPadsNewPrintFL :: UString -> [LString] -> Maybe Pat -> BranchInfo -> Q [Dec]+genPadsNewPrintFL name args patM branch = do+ let rm = [mkName "rep", mkName "md"]+ matches <- genPrintBranchInfo False branch+ let body = CaseE (TupE (map VarE rm)) matches+ return [mkPrinterFunction name args rm patM body]++-- | Generate the lazy function list printer for the Pads obtain syntactic form.+genPadsObtainPrintFL :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]+genPadsObtainPrintFL name args padsTy exp = do+ let rm = [mkName "rep", mkName "md"]+ body <- genPrintTy (PTransform padsTy (PTycon [name]) exp Nothing) $ Just $ TupE (map VarE rm)+ return [mkPrinterFunction name args rm Nothing body]++-- | Make the function declaration for the "lazy function list" printer with the+-- body as generated by 'genPrintTy', 'genPrintData', or 'genPrintBranchInfo' as+-- passed into this function as the last 'Exp' parameter.+mkPrinterFunction :: UString -> [LString] -> [Name] -> Maybe Pat -> Exp -> Dec+mkPrinterFunction name args rm patM body =+ FunD printerName [Clause (printerArgs ++ [TupP (map VarP rm)]) (NormalB body) []]+ where+ printerName = mkTyPrinterName name+ printerArgs = map (VarP . mkTyPrinterVarName) args ++ Maybe.maybeToList patM++-------------------------------------------------------------------------------+-- * Generate Printing Function from a Type++-- | Generate the body of the printing function for a Pads type - this function+-- dispatches to the ones below according to the syntactic form being+-- translated.+genPrintTy :: PadsTy -> Maybe Exp -> Q Exp+genPrintTy (PConstrain pat ty exp) rm = genPrintTy ty rm -- XXX: doesn't check the constraint; ideally we should change @printFL@ to account for possible printing errors+genPrintTy (PTransform src dest exp _) rm = genPrintTrans src exp rm+genPrintTy (PList ty sepM termM) rm = genPrintList ty sepM termM >>= applyPrintTy rm+genPrintTy (PPartition ty exp) rm = [| (error "genPrintTy PPartition not implemented") |] --genPrintPartition ty exp rm+genPrintTy (PApp tys expM) rm = genPrintTyApp tys expM >>= applyPrintTy rm+genPrintTy (PTuple tys) rm = genPrintTuple tys rm+genPrintTy (PExpression exp) rm = genPrintExp exp rm+genPrintTy (PTycon c) rm = genPrintTycon c >>= applyPrintTy rm+genPrintTy (PTyvar v) rm = genPrintTyVar v >>= applyPrintTy rm+genPrintTy (PValue exp ty) rm = genPrintValue exp rm++-- | Generate the printer for the Pads Value syntactic form 'PValue'. Because a+-- pads value is something that wasn't parsed (it's a way to compute / add an extra+-- field to a parsed Haskell record), we just return the 'nil' printer (prints+-- nothing).+genPrintValue :: Exp -> Maybe Exp -> Q Exp+genPrintValue exp rm = return $ VarE 'nil++-- | Generate the printer for the Pads Transform syntactic form 'PTransform'.+-- This means we need to grab the second function from the tuple provided by the+-- Pads programmer which corresponds to the inverse of the transform function,+-- and print the format of the resulting (source) type. Source here means what's+-- read from a file and destination type means the type for which we have a+-- value that we want to print out. In order for round-trip parsing to work, we+-- need to reverse the transformation because the on-disk format of the source+-- type is usually different from the on-disk format of the destination type.+genPrintTrans :: PadsTy -> Exp -> Maybe Exp -> Q Exp+genPrintTrans tySrc exp Nothing+ = genPrintTy tySrc Nothing+genPrintTrans tySrc (TupE [_, fncn]) (Just rm) = do+ rm' <- [| $(return fncn) $(return rm) |]+ genPrintTy tySrc (Just rm')+genPrintTrans _ tup _ = error ("Template Haskell exp '" ++ show tup ++ "' does not appear to be a two-tuple.")++-- | Some of the printing utilities provided by the runtime system need to know+-- about the representation and the metadata. If the first argument to this+-- function is Nothing, then we don't need to pass the representation and+-- metadata to the expression / utility (e.g. ca case expression printing a+-- union type). Otherwise the first argument contains 'Just' the '(rep, md)'+-- tuple brought into scope as the first parameter to the "*_printFL" functions+-- (e.g. the 'printList' runtime system function needs to know about the rep and+-- md).+applyPrintTy :: Maybe Exp -> Exp -> Q Exp+applyPrintTy rm f = do+ case rm of+ Nothing -> return f+ Just repmdE -> return $ AppE f repmdE++-- | Generate the template haskell code for printing a 'PList' Pads type.+genPrintList :: PadsTy -> Maybe PadsTy -> Maybe TermCond -> Q Exp+genPrintList ty sepOpt termCondOpt = do+ (elemRepE, elemRepP) <- doGenPE "elemrep"+ (elemMDE, elemMDP) <- doGenPE "elemmd"+ parseElemE <- genPrintTy ty $ Just $ TupE [elemRepE,elemMDE]+ let parseElemFnE = LamE [TupP [elemRepP, elemMDP]] parseElemE+ sepElemE <- case sepOpt of+ Nothing -> return (VarE 'printNothing)+ Just ty -> do+ def <- genDefTy ty+ genPrintTy ty $ Just $ TupE [SigE def (mkRepTy ty),SigE (VarE 'myempty) (mkMDTy False ty)]+ termElemE <- case termCondOpt of+ Nothing -> return (VarE 'printNothing)+ Just (LLen _) -> return (VarE 'printNothing)+ Just (LTerm (PApp [PTycon ["Try"],_] _)) -> return (VarE 'printNothing)+ Just (LTerm (PTuple [PApp [PTycon ["Try"],_] _])) -> return (VarE 'printNothing)+ Just (LTerm termTy) -> do+ def <- genDefTy termTy+ genPrintTy termTy $ Just $ TupE [SigE def (mkRepTy termTy),SigE (VarE 'myempty) (mkMDTy False termTy)]+ return $ appE3 (VarE 'printList) parseElemFnE sepElemE termElemE++-- | Generate the template haskell code for printing a Pads type application by+-- recursively calling 'genPrintTy' on the Pads types of each of the arguments to the+-- Pads type constructor.+genPrintTyApp :: [PadsTy] -> Maybe Exp -> Q Exp+genPrintTyApp tys expM = do+ prtys <- mapM (flip genPrintTy Nothing) tys+ foldl1M (\e1 e2 -> return $ AppE e1 e2) (prtys ++ Maybe.maybeToList expM)++-- | Generate the template haskell code for printing a Pads tuple type.+genPrintTuple :: [PadsTy] -> Maybe Exp -> Q Exp+genPrintTuple tys (Just rm) = do+ repNamesM <- genNamesforTuple True "rep" tys+ let repVars = map VarE (Maybe.catMaybes repNamesM)+ let repPats = map VarP (Maybe.catMaybes repNamesM)+ mdNamesM <- genNamesforTuple False "md" tys+ let mdVars = map VarE (Maybe.catMaybes mdNamesM)+ let mdPats = map VarP (Maybe.catMaybes mdNamesM)+ inners <- sequence [genPrintTupleInner t r m | (t,r,m) <- zip3 tys repNamesM mdNamesM{-, hasRep t-}]+ return $ CaseE rm+ [Match (TupP [TupP $ repPats, TupP [SigP WildP (ConT ''Base_md), (TupP mdPats)]])+ (NormalB (VarE 'concatFL `AppE` ListE inners))+ []]+genPrintTuple tys Nothing = do+ repName <- newName "rep"+ mdName <- newName "md"+ liftM (LamE [TupP [VarP repName,VarP mdName]]) $ genPrintTuple tys $ Just $ TupE [VarE repName,VarE mdName]++-- | Filters a second list based on which corresponding Pads types from the+-- first list have an underlying representation in memory (removing the ones+-- that don't have an underlying representation).+filterByHasRep :: [PadsTy] -> [a] -> [a]+filterByHasRep tys xs = map snd $ filter (hasRep . fst) (zip tys xs)++-- | Generate a list of names to be used as Haskell pattern variables and+-- expression variables for a Pads tuple type. If the tuple is for the+-- representation then the given 'Bool' is True and we want to ignore data that+-- doesn't have a representation in memory. Otherwise the tuple is for the+-- metadata meaning the given 'Bool' is False and we want to print *everything*.+genNamesforTuple :: Bool -> String -> [PadsTy] -> Q [Maybe Name]+genNamesforTuple False str tys = sequence [fmap Just (newName str) | ty <- tys]+genNamesforTuple True str tys = sequence [if hasRep ty then fmap Just (newName str) else return Nothing | ty <- tys]++-- | Generate the template haskell print function for some type inside of a+-- tuple based on whether or not that type has an in-memory representation+-- '(Just r)' and a metadata representation '(Just m)'.+genPrintTupleInner t (Just r) (Just m) = genPrintTy t (Just (TupE [VarE r,VarE m]))+genPrintTupleInner t Nothing (Just m) = genDefTy t >>= \def -> genPrintTy t (Just (TupE [def, VarE m]))+genPrintTupleInner t Nothing Nothing = genPrintTy t Nothing+genPrintTupleInner t (Just r) Nothing = error ("genPrintTupleInner: Type '" ++ show t+ ++ "' has a representation but no metadata.")++-- | Generate the template haskell code for printing the value of a Pads literal+-- (string, character, regex) by simply constructing a runtime system call to+-- 'litPrint' with the code for computing the Haskell value of the literal+-- spliced into the first argument position.+genPrintExp :: Exp -> Maybe Exp -> Q Exp+genPrintExp e _ = [| litPrint $(return e) |]++-- | Generate the printer for a Pads type constructor (hint: it's just the+-- variable name according to 'mkTyPrinterQName'.+genPrintTycon :: QString -> Q Exp+genPrintTycon c = return $ VarE (mkTyPrinterQName c)++-- | Generate the printing expression for a Pads type variable according to+-- 'mkTyPrinterVarName'.+genPrintTyVar :: LString -> Q Exp+genPrintTyVar v = return $ VarE (mkTyPrinterVarName v)++-------------------------------------------------------------------------------+-- Generate Printing Function from a Datatype++-- | Generate the template haskell expression for printing a Haskell value given+-- the Pads data type declaration defining the type of the Haskell value.+genPrintData :: PadsData -> Maybe Exp -> Q Exp+genPrintData (PUnion bs) rm = genPrintUnion bs rm+genPrintData (PSwitch exp pbs) rm = genPrintSwitch exp pbs rm++-- | Generate a Haskell case expression for printing a Pads union type.+genPrintUnion :: [BranchInfo] -> Maybe Exp -> Q Exp+genPrintUnion bs (Just rm) = do+ let doDef = if length bs > 1 then True else False+ matches <- liftM concat $ mapM (genPrintBranchInfo doDef) bs+ return $ CaseE rm matches+genPrintUnion bs Nothing = do+ repName <- newName "rep"+ mdName <- newName "md"+ let doDef = if length bs > 1 then True else False+ matches <- liftM concat $ mapM (genPrintBranchInfo doDef) bs+ return $ LamE [TupP [VarP repName,VarP mdName]] $ CaseE (TupE [VarE repName,VarE mdName]) matches++-- | Generate the printing function body of an individual branch of a Pads data type.+genPrintBranchInfo :: Bool -> BranchInfo -> Q [Match]+genPrintBranchInfo doDef (BRecord c fields predM) = genPrintRecord c fields predM+genPrintBranchInfo doDef (BConstr c args predM) = genPrintConstr doDef c args predM++-- | Generate the individual 'Match' of the Haskell case expression for matching+-- on a record being printed.+genPrintRecord :: UString -> [FieldInfo] -> Maybe Exp -> Q [Match]+genPrintRecord (mkName -> recName) fields predM = do+ (repEs, repPs) <- getPEforFields (\t -> genDefTy t >>= \def -> return $ SigE def (mkRepTy t)) (return . getBranchNameL) fields+ (mdEs, mdPs) <- getPEforFields (return . SigE (VarE 'myempty) . mkMDTy False) (return . getBranchMDNameL) fields+ let ptys = map (\(n,(_,ty),p,_) -> ty) fields+ let ty_rep_mds = zip3 ptys repEs mdEs+ expE <- mapM (\(ty,r,m) -> genPrintTy ty $ Just $ TupE [r,m]) ty_rep_mds+ let printItemsE = ListE expE+ let caseBody = NormalB (AppE (VarE 'concatFL) printItemsE)+ let mdPat = TupP[WildP, RecP (getStructInnerMDName recName) mdPs]+ let repPat = RecP recName repPs+ let casePat = TupP [repPat, mdPat]+ let match = Match casePat caseBody []+ return [match]++-- | Get the printer expression for an individual field of a record.+getPEforField :: (PadsTy -> Q Exp) -> (String -> Q Name) -> FieldInfo -> Q (Exp, Maybe FieldPat)+getPEforField def mkFieldNm (nameOpt, (strict,pty), optPred, _) = case nameOpt of+ Nothing -> def pty >>= \d -> return (d,Nothing)+ Just str -> do+ name <- mkFieldNm str+ let (varE, varP) = genPE name+ return (varE, Just (name, varP))++-- | Get the printer expressions and corresponding record field pattern+-- matches for each of the given 'FieldInfo's.+getPEforFields :: (PadsTy -> Q Exp) -> (String -> Q Name) -> [FieldInfo] -> Q ([Exp], [FieldPat])+getPEforFields def mkFieldNm fields = do+ eps <- mapM (getPEforField def mkFieldNm) fields+ let (es, pOpts) = List.unzip eps+ ps = Maybe.catMaybes pOpts+ return (es, ps)++-- | Generate the template haskell code for matching on and printing the value+-- for a Pads value constructor.+genPrintConstr :: Bool -> String -> [ConstrArg] -> (Maybe Exp) -> Q [Match]+genPrintConstr doDef (mkName -> recName) args predM = do+ let fields = map (\c -> (Just "arg",c,Nothing,Nothing)) args+ (repEs, repPs) <- getPEforFields (\t -> genDefTy t >>= \def -> return $ SigE def (mkRepTy t)) newName fields+ (mdEs, mdPs) <- getPEforFields (return . SigE (VarE 'myempty) . mkMDTy False) newName fields+ let ptys = map (\(n,(s,ty),p,_) -> ty) fields++ let genBody mdEs = (do+ { let genTyRepMd = (\(ty,r,m) -> if hasRep ty then return (ty,r,m) else genDefTy ty >>= (\def -> return (ty,SigE def (mkRepTy ty),m)))+ ; ty_rep_mds <- mapM genTyRepMd $ zip3 ptys repEs mdEs+ ; expE <- mapM (\(ty,repE,mdE) -> genPrintTy ty $ Just $ TupE [repE,mdE]) ty_rep_mds+ ; let printItemsE = ListE expE+ ; let caseBody = NormalB (AppE (VarE 'concatFL) printItemsE)+ ; return caseBody+ })++ let repPat = ConP recName (filterByHasRep ptys $ map snd repPs)+ let mdPat = TupP[SigP WildP (ConT ''Base_md), ConP (getStructInnerMDName recName) (map snd mdPs)]++ caseBody <- genBody mdEs+ let match = Match (TupP [repPat, mdPat]) caseBody []++ caseBodyDef <- genBody $ map (\(_,ty) -> SigE (VarE 'myempty) (mkMDTy False ty)) args+ let matchDef = Match (TupP [repPat,WildP]) caseBodyDef []+ if doDef then return [match,matchDef] else return [match]++-- | Generate the template haskell code for printing a Pads switch type by+-- ignoring the value we're switching on and simply generating the same case+-- expression that 'genPrintUnion' does for a Pads union type.+genPrintSwitch :: Exp -> [(Pat,BranchInfo)] -> Maybe Exp -> Q Exp+genPrintSwitch exp pbs rm = genPrintUnion (map snd pbs) rm++-------------------------------------------------------------------------------+-- * Generating Default Function from a Declaration++-- | Generate the Pads default value for a 'PadsDeclType'+genPadsDef :: UString -> [LString] -> Maybe Pat -> PadsTy -> Q [Dec]+genPadsDef name args patM padsTy = do+ body <- genDefTy padsTy+ return [mkDefFunction name args patM body]++-- | Generate the Pads default value for a Pads data declaration.+genPadsDataDef :: UString -> [LString] -> Maybe Pat -> PadsData -> Q [Dec]+genPadsDataDef name args patM padsData = do+ body <- genDefData padsData+ return [mkDefFunction name args patM body]++-- | Generate the Pads default value for a Pads newtype declaration.+genPadsNewDef :: UString -> [LString] -> Maybe Pat -> BranchInfo -> Q [Dec]+genPadsNewDef name args patM branch = do+ body <- genDefBranchInfo branch+ return [mkDefFunction name args patM body]++-- | Generate the Pads default value for a Pads obtain declaration.+genPadsObtainDef :: UString -> [LString] -> PadsTy -> Exp -> Q [Dec]+genPadsObtainDef name args padsTy exp = do+ body <- genDefTy (PTransform padsTy (PTycon [name]) exp Nothing)+ return [mkDefFunction name args Nothing body]++-- | Generate the Pads default value as a function declaration of the form+-- "foo_def" for a Pads parser named "Foo".+mkDefFunction :: UString -> [LString] -> Maybe Pat -> Exp -> Dec+mkDefFunction name args patM body =+ FunD defName [Clause (defArgs) (NormalB body) []]+ where+ defName = mkTyDefName name+ defArgs = map (VarP . mkTyDefVarName) args ++ Maybe.maybeToList patM++-------------------------------------------------------------------------------+-- * Generate Default Function from a Type++-- | Generate the default Haskell value for some Pads type.+genDefTy :: PadsTy -> Q Exp+genDefTy (PConstrain pat ty exp) = genDefTy ty -- XXX: doesn't check the constraint; ideally we should change @printFL@ to account for possible printing errors+genDefTy (PTransform src dest exp _) = do+ defSrc <- genDefTy src+ srcToDest <- [| \rep -> fst $ (fst $(return exp)) S.zeroSpan (rep,(error "TODO defaultMd")) |] -- XXX: fix this undefined, it kind of requires defaultMd to be defined inductively over Pads types as well...+ return $ AppE srcToDest defSrc+genDefTy (PList ty sepM termM) = [| [] |]+genDefTy (PPartition ty exp) = genDefTy ty+genDefTy (PApp tys expM) = do+ prtys <- mapM genDefTy tys+ foldl1M (\e1 e2 -> return $ AppE e1 e2) (prtys ++ Maybe.maybeToList expM)+genDefTy (PTuple tys) = genDefTuple tys+genDefTy (PExpression exp) = return exp+genDefTy (PTycon c) = return $ VarE (mkTyDefQName c)+genDefTy (PTyvar v) = return $ VarE (mkTyDefVarName v)+genDefTy (PValue exp ty) = genDefTy ty++-- | Generate the default Haskell value for a Pads tuple type.+genDefTuple :: [PadsTy] -> Q Exp+genDefTuple tys = case reps of+ [] -> [| () |]+ [ty] -> genDefTy ty+ tys -> do+ exps <- mapM genDefTy tys+ return $ TupE exps+ where+ reps = [ty | ty <- tys, hasRep ty]++-------------------------------------------------------------------------------+-- Generate Default Function from a Datatype++-- | Generate the default Haskell value for a Pads data type 'PadsData'.+genDefData :: PadsData -> Q Exp+genDefData (PUnion (b:bs)) = genDefBranchInfo b+genDefData (PSwitch exp (pb:pbs)) = genDefBranchInfo (snd pb)+genDefData (PUnion []) = error "genDefData: empty PUnion."+genDefData (PSwitch exp []) = error "genDefData: empty PSwitch."++-- | Generate the default Haskell value for a single branch of a Pads type,+-- namely either a Pads constructor or record.+genDefBranchInfo :: BranchInfo -> Q Exp+genDefBranchInfo (BConstr c args pred) = do+ reps <- sequence $ [genDefTy ty | (strict,ty) <- args, hasRep ty]+ return $ foldl1 AppE (ConE (mkConstrName c):reps)+genDefBranchInfo (BRecord c fields expM) = do+ reps <- sequence $ [liftM (l,) (genDefTy ty) | (Just l,(strict,ty),_,_) <- fields, hasRep ty]++ let lets = flip map reps $ \(lab,def) -> ValD (VarP $ mkName lab) (NormalB def) []+ return $ LetE lets $ foldl1 AppE (ConE (mkConstrName c):map (VarE . mkName . fst) reps)++-------------------------------------------------------------------------------+-- * Name Manipulation Functions++-- ** Naming types, and accessing the names of types++-- | Get the template haskell 'Name' for a given Pads type.+mkRepName :: String -> Name+mkRepName str = mkName str++-- | Make the template haskell 'Name' of a given 'PTycon' with a qualified name.+mkRepQName :: QString -> Name+mkRepQName str = mkName (qName str)++-- | Make externally visible metadata name for a Pads type+mkMDName :: String -> Name+mkMDName str = mkName (str ++ "_md")++-- | Given a Pads type name in the template haskell @Q@ monad, get the metadata+-- type name.+mkMDQName :: QString -> Name+mkMDQName str = mkName (appendTo str "_md")++-- | Make the internal metadata type name for a given Pads type+mkIMDName name = mkName (name ++ "_imd")++-- | Make externally visible metadata name for a Pads variable+mkMDVarName name = mkName (name ++ "_md")++-- ** Naming fields and constructors++-- | Convert Pads source (record) field name into a 'Q' monad name+mkFieldName str = mkName str++-- | Convert Pads source (record) field name into its metadata name in the 'Q'+-- monad.+mkFieldMDName str = mkName (str ++ "_md")++-- | Pads constructor+mkConstrName str = mkName str+mkConstrIMDName str = mkName (str ++ "_imd")+mkfnMDName str = mkName (strToLower str ++ "_md")+++-- ** Naming Parsers++mkTyParserName str = mkName (strToLower str ++ "_parseM")+mkTyParserSName str = mkName (strToLower str ++ "_parseS")++mkTyParserQName str = mkName (appendLower str "_parseM")+mkTyParserSQName str = mkName (appendLower str "_parseS")++mkVarParserName str = mkName (strToLower str ++ "__p")+++-- ** Naming Printers++getBranchMDNameU str = mkName ((strToUpper str)++"_md")+getBranchMDNameL str = mkName ((strToLower str)++"_md")+getBranchNameU str = mkName (strToUpper str)+getBranchNameL str = mkName (strToLower str)+getStructInnerMDName name = let str = show name in mkName (str++"_imd")++mkTyPrinterName str = mkName (strToLower str ++ "_printFL")+mkTyPrinterQName str = mkName (appendLower str "_printFL")+mkTyPrinterVarName str = mkName (str ++ "__pr")++mkTyDefName str = mkName (strToLower str ++ "_def")+mkTyDefQName str = mkName (appendLower str "_def")+mkTyDefVarName str = mkName (str ++ "__d")+++-- ** Naming Generators++mkTyGeneratorName str = mkName (strToLower str ++ "_genM")+mkTyGeneratorQName str = mkName (appendLower str "_genM")+mkVarGeneratorName str = mkName (strToLower str ++ "__g")++-- ** Naming Serializers++mkTySerializerName str = mkName (strToLower str ++ "_serialize")+mkTySerializerQName str = mkName (appendLower str "_serialize")+mkTySerializerVarName str = mkName (str ++ "__s")+++appendTo :: QString -> String -> String+appendTo ms s = qName (init ms ++ [last ms ++ s])+appendLower ms s = qName (init ms ++ [strToLower (last ms) ++ s])++type UString = String+type LString = String++foldl1M :: Monad m => (a -> a -> m a) -> [a] -> m a+foldl1M f (x:xs) = foldM f x xs++foldr1M :: Monad m => (a -> a -> m a) -> [a] -> m a+foldr1M f [x] = return x+foldr1M f (x:xs) = f x =<< foldr1M f xs++appT2 f x y = AppT (AppT f x) y++appE3 f x y z = AppE (AppE (AppE f x) y) z
@@ -0,0 +1,1298 @@+{-# LANGUAGE TypeFamilies, GeneralizedNewtypeDeriving, TemplateHaskell, ScopedTypeVariables,+ MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances,+ FlexibleInstances, UndecidableInstances, DeriveLift #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.CoreBaseTypes+ Description : Core Pads base types with parsers+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.CoreBaseTypes where++import Language.Pads.Generic+import Language.Pads.MetaData+import Language.Pads.PadsParser+import Language.Pads.RegExp+import Data.Maybe++import qualified Language.Pads.Source as S+import qualified Language.Pads.Errors as E+import qualified Data.ByteString as B+import Data.ByteString.Internal+import qualified Data.ByteString.Char8 as C++import Language.Pads.PadsPrinter+import Language.Pads.Generation++import Language.Haskell.TH as TH+import Language.Haskell.TH.Syntax+import Data.Data+import qualified Data.Map as M+import qualified Data.List as List+import Data.Word+import Data.Char as Char+import Data.Int+import Data.Bits++import Text.PrettyPrint.Mainland as PP+import Text.PrettyPrint.Mainland.Class++import Control.Monad+import Control.Monad.Reader+import System.IO.Unsafe (unsafePerformIO)+++-- | Metadata type for a PADS Char+type Char_md = Base_md++-- | Monadic parser for a PADS Char+char_parseM :: PadsParser (Char, Base_md)+char_parseM =+ handleEOF def "Char" $+ handleEOR def "Char" $ do+ c <- takeHeadP+ returnClean c++-- | Default value inserted by the parser for a PADS Char+char_def :: Char+char_def = 'X'++type instance PadsArg Char = ()+type instance Meta Char = Base_md+instance Pads1 () Char Base_md where+ parsePP1 () = char_parseM+ printFL1 () = char_printFL+ def1 () = char_def++char_printFL :: PadsPrinter (Char, md)+char_printFL (c,bmd) = addString [c]++char_genM :: PadsGen st Char+char_genM = randLetter++char_serialize :: Char -> CList+char_serialize c = toCL [CharChunk c]++---------------------------------------------++type BitBool = Bool+type BitBool_md = Base_md++bitBool_parseM :: PadsParser (BitBool, Base_md)+bitBool_parseM =+ handleEOF False "BitBool" $+ handleEOR False "BitBool" $ do+ b <- takeBits8P 1+ returnClean (b == 1)++bitBool_def = False++bitBool_printFL :: PadsPrinter (BitBool, md)+bitBool_printFL (bb,bbmd) = fshow bb++bitBool_genM :: PadsGen st BitBool+bitBool_genM = randElem [False,True]++bitBool_serialize :: BitBool -> CList+bitBool_serialize b = toCL [BinaryChunk ((fromIntegral . fromEnum) b) 1]++-- type instance PadsArg Bool = ()+-- type instance Meta Bool = Base_md+-- instance Pads1 () Bool Base_md where+-- parsePP1 () = bitBool_parseM+-- printFL1 () = bitBool_printFL+-- def1 () = bitBool_def++-----------------------------------------------------------------++type BitField = Integer+type BitField_md = Base_md++bitField_parseM :: Integral a => a -> PadsParser (BitField, Base_md)+bitField_parseM x =+ if x < 0+ then returnError def (E.BitWidthError 0 (fromIntegral x))+ else handleEOF 0 "BitField" $+ handleEOR 0 "BitField" $ do+ b <- takeBitsP x+ returnClean b++bitField_def :: a -> BitField+bitField_def _ = 0++bitField_printFL :: Integral a => a -> PadsPrinter (BitField, md)+bitField_printFL _ (x, xmd) = fshow x++bitField_genM :: Integral a => a -> PadsGen st BitField+bitField_genM x = randIntegerBound (2^x - 1)++bitField_serialize :: Integral a => a -> BitField -> CList+bitField_serialize b v = toCL [BinaryChunk v (fromIntegral b)]+++type Bits8 = Word8+type Bits8_md = Base_md++bits8_parseM :: Integral a => a -> PadsParser (Bits8, Base_md)+bits8_parseM x =+ if x < 1 || x > 8+ then returnError 0 (E.BitWidthError 8 (fromIntegral x))+ else handleEOF 0 "Bits8" $+ handleEOR 0 "Bits8" $ do+ b <- takeBits8P x+ returnClean b++bits8_def :: a -> Bits8+bits8_def _ = 0++bits8_printFL :: Integral a => a -> PadsPrinter (Bits8, md)+bits8_printFL _ (x, xmd) = fshow x++bits8_genM :: Integral a => a -> PadsGen st Bits8+bits8_genM x = randNumBound (2^x - 1)++bits8_serialize :: Int -> Bits8 -> CList+bits8_serialize b v = toCL [BinaryChunk (fromIntegral v) b]+++type Bits16 = Word16+type Bits16_md = Base_md++bits16_parseM :: Integral a => a -> PadsParser (Bits16, Base_md)+bits16_parseM x =+ if x < 1 || x > 16+ then returnError 0 (E.BitWidthError 16 (fromIntegral x))+ else handleEOF 0 "Bits16" $+ handleEOR 0 "Bits16" $ do+ b <- takeBits16P x+ returnClean b++bits16_def :: a -> Bits16+bits16_def _ = 0++bits16_printFL :: Integral a => a -> PadsPrinter (Bits16, md)+bits16_printFL _ (x, xmd) = fshow x++bits16_genM :: Integral a => a -> PadsGen st Bits16+bits16_genM x = randNumBound (2^x - 1)++bits16_serialize :: Int -> Bits16 -> CList+bits16_serialize b v = toCL [BinaryChunk (fromIntegral v) b]+++type Bits32 = Word32+type Bits32_md = Base_md++bits32_parseM :: Integral a => a -> PadsParser (Bits32, Base_md)+bits32_parseM x =+ if x < 1 || x > 32+ then returnError 0 (E.BitWidthError 32 (fromIntegral x))+ else handleEOF 0 "Bits32" $+ handleEOR 0 "Bits32" $ do+ b <- takeBits32P x+ returnClean b++bits32_def :: a -> Bits32+bits32_def _ = 0++bits32_printFL :: Integral a => a -> PadsPrinter (Bits32, md)+bits32_printFL _ (x, xmd) = fshow x++bits32_genM :: Integral a => a -> PadsGen st Bits32+bits32_genM x = randNumBound (2^x - 1)++bits32_serialize :: Int -> Bits32 -> CList+bits32_serialize b v = toCL [BinaryChunk (fromIntegral v) b]+++type Bits64 = Word64+type Bits64_md = Base_md++bits64_parseM :: Integral a => a -> PadsParser (Bits64, Base_md)+bits64_parseM x =+ if x < 1 || x > 64+ then returnError 0 (E.BitWidthError 64 (fromIntegral x))+ else handleEOF 0 "Bits64" $+ handleEOR 0 "Bits64" $ do+ b <- takeBits64P x+ returnClean b++bits64_def :: a -> Bits64+bits64_def _ = 0++bits64_printFL :: Integral a => a -> PadsPrinter (Bits64, md)+bits64_printFL _ (x, xmd) = fshow x++bits64_genM :: Integral a => a -> PadsGen st Bits64+bits64_genM x = randNumBound (2^x - 1)++bits64_serialize :: Int -> Bits64 -> CList+bits64_serialize b v = toCL [BinaryChunk (fromIntegral v) b]++-----------------------------------------------------------------++--type Int+type Int_md = Base_md++-- | Monadic parser for a PADS Int+int_parseM :: PadsParser (Int,Base_md)+int_parseM =+ handleEOF def "Int" $+ handleEOR def "Int" $ do+ c <- peekHeadP+ let isNeg = (c == '-')+ when isNeg (takeHeadP >> return ())+ digits <- satisfy Char.isDigit+ if not (null digits)+ then returnClean (digitListToInt isNeg digits)+ else returnError def (E.FoundWhenExpecting (mkStr c) "Int")++-- | Default value inserted by the parser for a PADS Int+int_def :: Int+int_def = 0++type instance PadsArg Int = ()+type instance Meta Int = Base_md+instance Pads1 () Int Base_md where+ parsePP1 () = int_parseM+ printFL1 () = int_printFL+ def1 () = int_def++int_printFL :: PadsPrinter (Int, Base_md)+int_printFL (i, bmd) = fshow i++int_genM :: PadsGen st Int+int_genM = randNum++int_serialize :: Int -> CList+int_serialize i = toCL $ map CharChunk $ show i++-----------------------------------------------------------------++--type Integer+type Integer_md = Base_md++-- | Monadic parser for a PADS Integer+integer_parseM :: PadsParser (Integer,Base_md)+integer_parseM =+ handleEOF def "Integer" $+ handleEOR def "Integer" $ do+ c <- peekHeadP+ let isNeg = (c == '-')+ when isNeg (takeHeadP >> return ())+ digits <- satisfy Char.isDigit+ if not (null digits)+ then returnClean (toEnum $ digitListToInt isNeg digits)+ else returnError def (E.FoundWhenExpecting (mkStr c) "Integer")++-- | Default value inserted by the parser for a PADS Integer+integer_def :: Integer+integer_def = 0++type instance PadsArg Integer = ()+type instance Meta Integer = Base_md+instance Pads1 () Integer Base_md where+ parsePP1 () = integer_parseM+ printFL1 () = integer_printFL+ def1 () = integer_def++integer_printFL :: PadsPrinter (Integer, Base_md)+integer_printFL (i, bmd) = fshow i++integer_genM :: PadsGen st Integer+integer_genM = randInteger++integer_serialize :: Integer -> CList+integer_serialize i = toCL $ map CharChunk $ show i++-----------------------------------------------------------------++--type Float+type Float_md = Base_md++-- | Monadic parser for a PADS Float, e.g. "-3.1415"+float_parseM :: PadsParser (Float,Base_md)+float_parseM =+ handleEOF def "Float" $+ handleEOR def "Float" $ do+ -- Get leading sign+ c <- peekHeadP+ let isNeg = (c == '-')+ when isNeg (takeHeadP >> return ())+ let sign = if isNeg then "-" else ""+ -- Get digits before any dot+ digits1 <- satisfy Char.isDigit+ -- Get optional dot+ d <- peekHeadP+ let hasDot = (d == '.')+ when hasDot (takeHeadP >> return ())+ let dec = if hasDot then "." else ""+ -- Get digits after dot+ digits2 <- satisfy Char.isDigit+ -- Get optional exponent marker+ e <- peekHeadP+ let hasExp = (e == 'e')+ when hasExp (takeHeadP >> return ())+ let exp = if hasExp then "e" else ""+ -- Get optional exponent sign+ es <- peekHeadP+ let hasESign = (es == '-')+ when hasESign (takeHeadP >> return ())+ let expSign = if hasESign then "-" else ""+ -- Get digits in the exponent+ digits3 <- satisfy Char.isDigit+ -- As long as the double had digits+ if not (null digits1)+ then returnClean (read (sign ++digits1++dec++digits2++exp++expSign++digits3))+ else returnError def (E.FoundWhenExpecting (mkStr c) "Float")++-- | Default value inserted by the parser for a PADS Float+float_def :: Float+float_def = 0++type instance PadsArg Float = ()+type instance Meta Float = Base_md+instance Pads1 () Float Base_md where+ parsePP1 () = float_parseM+ printFL1 () = float_printFL+ def1 () = float_def++float_printFL :: PadsPrinter (Float, Base_md)+float_printFL (d, bmd) = fshow d++float_genM :: PadsGen st Float+float_genM = randNum++float_serialize :: Float -> CList+float_serialize f = toCL $ map CharChunk $ show f++-----------------------------------------------------------------++--type Double+type Double_md = Base_md++-- | Monadic parser for a textual PADS Double, e.g. "-3.1415"+double_parseM :: PadsParser (Double,Base_md)+double_parseM =+ handleEOF def "Double" $+ handleEOR def "Double" $ do+ -- Get leading sign+ c <- peekHeadP+ let isNeg = (c == '-')+ when isNeg (takeHeadP >> return ())+ let sign = if isNeg then "-" else ""+ -- Get digits before any dot+ digits1 <- satisfy Char.isDigit+ -- Get optional dot+ d <- peekHeadP+ let hasDot = (d == '.')+ when hasDot (takeHeadP >> return ())+ let dec = if hasDot then "." else ""+ -- Get digits after dot+ digits2 <- satisfy Char.isDigit+ -- Get optional exponent marker+ e <- peekHeadP+ let hasExp = (e == 'e')+ when hasExp (takeHeadP >> return ())+ let exp = if hasExp then "e" else ""+ -- Get optional exponent sign+ es <- peekHeadP+ let hasESign = (es == '-')+ when hasESign (takeHeadP >> return ())+ let expSign = if hasESign then "-" else ""+ -- Get digits in the exponent+ digits3 <- satisfy Char.isDigit+ -- As long as the double had digits+ if not (null digits1)+ then returnClean (read (sign ++digits1++dec++digits2++exp++expSign++digits3))+ else returnError def (E.FoundWhenExpecting (mkStr c) "Double")++-- | Default value inserted by the parser for a PADS Float+double_def :: Double+double_def = 0++type instance PadsArg Double = ()+type instance Meta Double = Base_md+instance Pads1 () Double Base_md where+ parsePP1 () = double_parseM+ printFL1 () = double_printFL+ def1 () = 0++double_printFL :: PadsPrinter (Double, Base_md)+double_printFL (d, bmd) = fshow d++double_genM :: PadsGen st Double+double_genM = randNum++double_serialize :: Double -> CList+double_serialize d = toCL $ map CharChunk $ show d++-----------------------------------------------------------------++-- tries to parse @a@ without consuming the input string+type Try a = a+type Try_md a_md = (Base_md, a_md)++try_parseM :: PadsMD md => PadsParser (rep,md) -> PadsParser (Try rep, Try_md md)+try_parseM p = do+ (rep,md) <- parseTry p+ return (rep, (cleanBasePD, md))++try_printFL :: PadsPrinter (a,a_md) -> PadsPrinter (Try a,Try_md a_md)+try_printFL p _ = printNothing++try_def :: a -> Try a+try_def d = d++try_genM :: PadsGen st a -> PadsGen st (Try a)+try_genM g = g >>= return++--try_serialize :: Try a -> CList+try_serialize = id+++-----------------------------------------------------------------++type Digit = Int+type Digit_md = Base_md++-- | Monadic parser for a PADS Digit according to @'isDigit'@+digit_parseM :: PadsParser (Digit, Base_md)+digit_parseM =+ handleEOF def "Pdigit" $+ handleEOR def "Pdigit" $ do+ c <- takeHeadP+ if isDigit c+ then returnClean (digitToInt c)+ else returnError def (E.FoundWhenExpecting [c] "Digit")++-- | Default value inserted by the parser for a PADS Digit+digit_def :: Digit+digit_def = 0++digit_printFL :: PadsPrinter (Digit, Base_md)+digit_printFL (i, bmd) = fshow i++digit_genM :: PadsGen st Digit+digit_genM = randNumBound 9++digit_serialize :: Digit -> CList+digit_serialize d = toCL $ map CharChunk $ show d+++-----------------------------------------------------------------++--type String+type String_md = Base_md++string_parseM :: PadsParser (String, Base_md)+string_parseM = do+ document <- getAllBinP+ returnClean $ C.unpack document++-- | Default value inserted by the parser for a PADS String+string_def = ""++type instance PadsArg String = ()+type instance Meta String = Base_md+instance Pads1 () String Base_md where+ parsePP1 () = string_parseM+ printFL1 () = string_printFL+ def1 () = string_def++string_printFL :: PadsPrinter (String, Base_md)+string_printFL (str, bmd) = addString str++string_genM :: PadsGen st String+string_genM = stringVW_genM 100++string_serialize :: String -> CList+string_serialize s = toCL $ map CharChunk s++-----------------------------------------------------------------+++newtype Text = Text S.RawStream+ deriving (Eq, Show, Data, Typeable, Ord)+type Text_md = Base_md++text_parseM :: PadsParser (Text, Base_md)+text_parseM = do+ document <- getAllBinP+ returnClean (Text document)++instance Pretty Text where+ ppr (Text str) = text "ASCII"++text_def :: Text+text_def = Text $ B.pack []++type instance PadsArg Text = ()+type instance Meta Text = Base_md+instance Pads1 () Text Base_md where+ parsePP1 () = text_parseM+ printFL1 () = text_printFL+ def1 () = text_def++text_printFL :: PadsPrinter (Text, Base_md)+text_printFL (Text str, bmd) = addBString str++text_genM :: PadsGen st Text+text_genM = Text <$> B.pack <$> (map S.chrToWord8) <$> stringVW_genM 500++text_serialize :: Text -> CList+text_serialize (Text b) = toCL $ ((map (CharChunk . S.word8ToChr)) . B.unpack) b++-----------------------------------------------------------------++newtype Binary = Binary S.RawStream+ deriving (Eq, Show, Data, Typeable, Ord)+type Binary_md = Base_md++binary_parseM :: PadsParser (Binary, Base_md)+binary_parseM = do+ document <- getAllBinP+ returnClean (Binary document)++instance Pretty Binary where+ ppr (Binary str) = text "Binary"++binary_def :: Binary+binary_def = Binary $ B.pack []++type instance PadsArg Binary = ()+type instance Meta Binary = Base_md+instance Pads1 () Binary Base_md where+ parsePP1 () = binary_parseM+ printFL1 () = binary_printFL+ def1 () = binary_def++binary_printFL :: PadsPrinter (Binary, Base_md)+binary_printFL (Binary bstr, bmd) = addBString bstr+++-----------------------------------------------------------------++-- | string with end character. Ex:+--+-- > StringC ','+type StringC = String+type StringC_md = Base_md++stringC_parseM :: Char -> PadsParser (StringC, Base_md)+stringC_parseM c =+ handleEOF (stringC_def c) "StringC" $+ handleEOR (stringC_def c) "StringC" $ do+ str <- satisfy (\c'-> c /= c')+ returnClean str++stringC_def c = ""++stringC_printFL :: Char -> PadsPrinter (StringC, Base_md)+stringC_printFL c (str, bmd) = addString str++stringC_genM :: Char -> PadsGen st StringC+stringC_genM c = do+ i <- randNumBound 500+ replicateM i (randLetterExcluding c)++stringC_serialize :: Char -> StringC -> CList+stringC_serialize c s = (string_serialize s) `cAppend` (toCL [CharChunk c])++-----------------------------------------------------------------+++-- | string of fixed length+type StringFW = String+type StringFW_md = Base_md++stringFW_parseM :: Int -> PadsParser (StringFW, Base_md)+stringFW_parseM 0 = returnClean ""+stringFW_parseM n =+ handleEOF (stringFW_def n) "StringFW" $+ handleEOR (stringFW_def n) "StringFW" $ do+ str <- takeP n+ if (length str) == n+ then returnClean str+ else returnError (stringFW_def n) (E.Insufficient (length str) n)++stringFW_def :: Int -> StringFW+stringFW_def n = replicate n 'X'++stringFW_printFL :: Int -> PadsPrinter (StringFW, Base_md)+stringFW_printFL n (str, bmd) = addString (take n str)++stringFW_genM :: Int -> PadsGen st StringFW+stringFW_genM i = replicateM i randLetter++stringFW_serialize :: Int -> StringFW -> CList+stringFW_serialize _ = string_serialize+++-----------------------------------------------------------------++-- | string of variable length+type StringVW = String+type StringVW_md = Base_md++stringVW_parseM :: Int -> PadsParser (StringVW, Base_md)+stringVW_parseM 0 = returnClean ""+stringVW_parseM n =+ handleEOF (stringVW_def n) "StringVW" $+ handleEOR (stringVW_def n) "StringVW" $ do+ str <- takeP n+ returnClean str++stringVW_def :: Int -> StringVW+stringVW_def n = replicate n 'X'++stringVW_printFL :: Int -> PadsPrinter (StringVW, Base_md)+stringVW_printFL n (str, bmd) = addString (take n str)++stringVW_genM :: Int -> PadsGen st StringVW+stringVW_genM x = do+ i <- randNumBound x+ replicateM i randLetter++stringVW_serialize :: Int -> StringVW -> CList+stringVW_serialize i s = string_serialize s++---- string of variable length (end if EOR)+--type StringVW = String+--type StringVW_md = Base_md+--+--stringVW_parseM :: (Bool,Int) -> PadsParser (StringVW, Base_md)+--stringVW_parseM (endIfEOR,0) = returnClean ""+--stringVW_parseM (endIfEOR,n) = do+-- let (doEOF, doEOR) = if endIfEOR then (checkEOF, checkEOR) else (handleEOF, handleEOR)+-- doEOF "" "StringVW" $ doEOR "" "StringVW" $ do+-- c1 <- takeHeadP+-- (rest, rest_md) <- stringVW_parseM (endIfEOR,pred n)+-- return (c1:rest, rest_md)+--+--stringVW_def (endIfEOR,n) = replicate n 'X'+--+--stringVW_printFL :: (Bool,Int) -> PadsPrinter (StringVW, Base_md)+--stringVW_printFL (endIfEOR,n) (str, bmd) = addString (take n str)++-----------------------------------------------------------------++-----------------------------------------------------------------++-- | string with matching expression. For example:+--+-- > [pads| type StrME = StringME 'a+' |]+type StringME = String+type StringME_md = Base_md++stringME_parseM :: RE -> PadsParser (StringME, Base_md)+stringME_parseM re =+ handleEOF (stringME_def re) "StringME" $ do+ match <- regexMatchP re+ case match of+ Just str -> returnClean str+ Nothing -> returnError (stringME_def re) (E.RegexMatchFail (show re))++stringME_def (RE re) = "" -- should invert the re+stringME_def (REd re d) = d++stringME_printFL :: RE -> PadsPrinter (StringME, Base_md)+stringME_printFL re (str, bmd) = addString str+ -- We're not likely to check that str matches re++stringME_genM :: RE -> PadsGen st StringME+stringME_genM _+ = error $ "stringME_genM unimplemented: consider using the workaround \"type "+ ++ "XYZ = obtain StringME (RE) from StringME (RE) using <| "+ ++ "(const id, id) |> generator (gen)\" in your description to "+ ++ "provide your own regex-specific generator."++stringME_serialize :: RE -> StringME -> CList+stringME_serialize _ s = string_serialize s++-----------------------------------------------------------------++-- | string matching given native regex. PADS uses posix regex (from the+-- regex-posix package). For example:+--+-- > [pads| StringSE <| RE "b|c" |>|]+type StringSE = String+type StringSE_md = Base_md++stringSE_parseM :: RE -> PadsParser (StringSE, Base_md)+stringSE_parseM re =+ checkEOF (stringSE_def re) "StringSE" $+ checkEOR (stringSE_def re) "StringSE" $ do+ match <- regexStopP re+ case match of+ Just str -> returnClean str+ Nothing -> returnError (stringSE_def re) (E.RegexMatchFail (show re))++stringSE_def (RE re) = "" -- should invert the re+stringSE_def (REd re d) = d++stringSE_printFL :: RE -> PadsPrinter (StringSE, Base_md)+stringSE_printFL re (str, bmd) = addString str++stringSE_genM :: RE -> PadsGen st StringSE+stringSE_genM r+ = error $ "stringSE_genM unimplemented: consider using the workaround \"type "+ ++ "XYZ = obtain StringSE (" ++ show r ++ ") from StringSE ("+ ++ show r ++ ") using <| (const id, id) |> generator (gen)\" in your "+ ++ "description to provide your own regex-specific generator."++stringSE_serialize :: RE -> StringSE -> CList+stringSE_serialize _ s = string_serialize s+++-----------------------------------------------------------------++-- | string with a predicate. For example:+--+-- > [pads| type Digits = StringP Char.isDigit |]+type StringP = String+type StringP_md = Base_md++stringP_parseM :: (Char -> Bool) -> PadsParser (StringP, Base_md)+stringP_parseM p =+ handleEOF (stringP_def p) "StringP" $+ handleEOR (stringP_def p) "StringP" $ do+ str <- satisfy p+ returnClean str++stringP_def _ = ""++stringP_printFL :: (Char -> Bool) -> PadsPrinter (StringP, Base_md)+stringP_printFL p (str, bmd) = addString str++stringP_genM :: (Char -> Bool) -> PadsGen st StringP+stringP_genM _+ = error $ "stringP_genM unimplemented: consider using the workaround \"type "+ ++ "XYZ = obtain StringP (pred) from StringP (pred) using <| "+ ++ "(const id, id) |> generator (gen)\" in your description to "+ ++ "provide your own predicate-specific generator."+++stringP_serialize :: (Char -> Bool) -> StringP -> CList+stringP_serialize _ s = string_serialize s+++-----------------------------------------------------------------++-- | string predicate with escape condition+type StringPESC = String+type StringPESC_md = Base_md++stringPESC_parseM :: (Bool, (Char, [Char])) -> PadsParser(StringPESC, Base_md)+stringPESC_parseM arg @ (endIfEOR, (escape, stops)) =+ let (doEOF, doEOR) = if endIfEOR then (checkEOF, checkEOR) else (handleEOF, handleEOR)+ in+ doEOF "" "StringPESC" $+ doEOR "" "StringPESC" $ do+ { c1 <- peekHeadP+ ; if c1 `elem` stops then+ returnClean ""+ else if c1 == escape then do+ { takeHeadP+ ; doEOF [c1] "StringPESC" $+ doEOR [c1] "StringPESC" $ do+ { c2 <- takeHeadP+ ; if (c2 == escape) || (c2 `elem` stops) then do+ { (rest, rest_md) <- stringPESC_parseM arg+ ; return (c2:rest, rest_md)+ }+ else do+ { (rest, rest_md) <- stringPESC_parseM arg+ ; return (c1:c2:rest, rest_md)+ }+ }+ } else do+ { c1 <- takeHeadP+ ; (rest, rest_md) <- stringPESC_parseM arg+ ; return (c1:rest, rest_md)+ }+ }++stringPESC_def :: (Bool, (Char, [Char])) -> String+stringPESC_def arg@(endIfEOR, (escape, stops)) = ""++stringPESC_printFL :: (Bool, (Char, [Char])) -> PadsPrinter (StringPESC, Base_md)+stringPESC_printFL (_, (escape, stops)) (str, bmd) =+ let replace c = if c `elem` stops then escape : [c] else [c]+ newStr = concat (map replace str)+ in addString newStr++stringPESC_genM :: (Bool, (Char, [Char])) -> PadsGen st StringPESC+stringPESC_genM _ = error "stringPESC_genM: unimplemented"++stringPESC_serialize :: (Bool, (Char, [Char])) -> StringPESC -> CList+stringPESC_serialize _ s = string_serialize s++-----------------------------------------------------------------+-- Non-byte-aligned (NB) types+++type CharNB = Char+type CharNB_md = Base_md++charNB_parseM :: PadsParser (CharNB, Base_md)+charNB_parseM =+ handleEOF def "CharNB" $+ handleEOR def "CharNB" $ do+ c <- takeBitsP 8+ returnClean (S.word8ToChr (fromIntegral c :: Word8))++charNB_def :: Char+charNB_def = char_def++charNB_printFL :: PadsPrinter (CharNB, md)+charNB_printFL (c, bmd) = addString [c]++charNB_genM :: PadsGen st CharNB+charNB_genM = char_genM++charNB_serialize :: CharNB -> CList+charNB_serialize = char_serialize++-----------------------------------------------------------------+++type StringNB = String+type StringNB_md = Base_md++stringNB_parseM :: PadsParser (String, Base_md)+stringNB_parseM = do+ str <- drainSourceNBP+ returnClean str++stringNB_def = string_def++stringNB_printFL :: PadsPrinter (String, Base_md)+stringNB_printFL = string_printFL++stringNB_genM :: PadsGen st StringNB+stringNB_genM = string_genM++-----------------------------------------------------------------++type StringCNB = String+type StringCNB_md = Base_md++stringCNB_parseM :: Char -> PadsParser (StringCNB, Base_md)+stringCNB_parseM c =+ handleEOF (stringCNB_def c) "StringCNB" $+ handleEOR (stringCNB_def c) "StringCNB" $ do+ str <- satisfyNBP (\c' -> c /= c')+ returnClean str++stringCNB_def :: Char -> StringCNB+stringCNB_def = stringC_def++stringCNB_printFL :: Char -> PadsPrinter (StringCNB, Base_md)+stringCNB_printFL = stringC_printFL++stringCNB_genM :: Char -> PadsGen st StringCNB+stringCNB_genM = stringC_genM++stringCNB_serialize :: Char -> StringC -> CList+stringCNB_serialize = stringC_serialize+++-----------------------------------------------------------------++type StringFWNB = String+type StringFWNB_md = Base_md++stringFWNB_parseM :: Int -> PadsParser (StringFW, Base_md)+stringFWNB_parseM 0 = returnClean ""+stringFWNB_parseM n =+ handleEOF (stringFWNB_def n) "StringFWNB" $+ handleEOR (stringFWNB_def n) "StringFWNB" $ do+ str <- takeBytesNBP n+ let str' = map S.word8ToChr (B.unpack str)+ if (length str') == n+ then returnClean str'+ else returnError (stringFWNB_def n) (E.Insufficient (length str') n)++stringFWNB_def :: Int -> StringFW+stringFWNB_def n = replicate n 'X'++stringFWNB_printFL :: Int -> PadsPrinter (StringFW, Base_md)+stringFWNB_printFL = stringFW_printFL++stringFWNB_genM :: Int -> PadsGen st StringFWNB+stringFWNB_genM = stringFW_genM++stringFWNB_serialize :: Int -> StringFWNB -> CList+stringFWNB_serialize _ = string_serialize++-----------------------------------------------------------------++type BytesNB = S.RawStream+type BytesNB_md = Base_md++bytesNB_parseM :: Int -> PadsParser (BytesNB, BytesNB_md)+bytesNB_parseM n =+ handleEOF (def1 n) "BytesNB" $+ handleEOR (def1 n) "BytesNB" $ do+ bytes <- takeBytesNBP n+ if B.length bytes == n+ then returnClean bytes+ else returnError (def1 n) (E.Insufficient (B.length bytes) n)++bytesNB_printFL :: Int -> PadsPrinter (BytesNB, BytesNB_md)+bytesNB_printFL = bytes_printFL++bytesNB_def :: Int -> BytesNB+bytesNB_def = bytes_def++bytesNB_genM :: Int -> PadsGen st BytesNB+bytesNB_genM = bytes_genM++bytesNB_serialize :: Int -> BytesNB -> CList+bytesNB_serialize = bytes_serialize++-----------------------------------------------------------------+++-- | Chunks represent an abstraction of literal data, and allow for easy+-- consumption and concatenation into one ByteString of data, which can be+-- written to disk. Each BinaryChunk represents the value val .&. (2^bits - 1)+data Chunk = CharChunk Char+ | BinaryChunk { val :: Integer, bits :: Int }+ deriving (Eq, Show, Lift)++-- | fromChunks provides a translation from Chunks to a list of bytes. It+-- accomplishes this in time linear to the length of the list of Chunks. It+-- converts each chunk into "bits" (a list of 1's and 0's), then splits that+-- into "bytes" (lists of length 8 each) to simplify combination in non-byte-+-- aligned cases.+fromChunks :: [Chunk] -> B.ByteString+fromChunks cs = let+ bits = concat $ chunksToBits cs+ toPad = case (8 - ((length bits) `mod` 8)) of 8 -> 0; x -> x+ padding = replicate toPad 0+ bytes = asBytes $ bits ++ padding+ in if (length (bits ++ padding) `mod` 8) /= 0+ then error "fromChunks: bug in binary conversion"+ else B.pack $ map fromBytes bytes+ where+ -- | Dispatches to toPaddedBits depending on Chunk type+ chunksToBits :: [Chunk] -> [[Word8]]+ chunksToBits [] = []+ chunksToBits ((CharChunk c):cs) =+ (toPaddedBits (fromEnum c) 8) : chunksToBits cs+ chunksToBits ((BinaryChunk v b):cs) =+ (toPaddedBits v b) : chunksToBits cs++ -- | Ensure every value includes the number of bits it's meant to, since+ -- toBits won't include 0s when necessary+ toPaddedBits :: Integral a => a -> Int -> [Word8]+ toPaddedBits x padTo = let+ x' = toBits x []+ padding = replicate (padTo - length x') 0+ in if (padTo - length x') < 0+ then drop (abs $ padTo - length x') x'+ else padding ++ x'++ -- | Straightforward decimal-to-bits conversion+ toBits :: Integral a => a -> [Word8] -> [Word8]+ toBits 0 [] = [0]+ toBits 0 bs = bs+ toBits x bs = toBits (x `div` 2) (fromIntegral x `mod` 2 : bs)++ -- | Split list of 1s and 0s into lists of length 8 each+ asBytes :: [Word8] -> [[Word8]]+ asBytes [] = []+ asBytes xs = (take 8 xs) : (asBytes $ drop 8 xs)++ -- | Convert a list of 8 bits into a decimal byte+ fromBytes :: [Word8] -> Word8+ fromBytes bs = let+ withPowers = zip bs (reverse [0..7])+ in foldr1 (+) (map (\(b,p) -> b * 2^p) withPowers)++type CList = [Chunk] -> [Chunk]++-- For debugging mostly+instance Show CList where+ show cl = show $ fromCL cl++cAppend :: CList -> CList -> CList+cs1 `cAppend` cs2 = cs1 . cs2++cConcat :: [CList] -> CList+cConcat cl = foldr cAppend id cl++toCL :: [Chunk] -> CList+toCL cs = (cs ++)++fromCL :: CList -> [Chunk]+fromCL cl = cl []++class ExpSerialize a where+ exp_serialize :: a -> CList++instance ExpSerialize Char where+ exp_serialize = char_serialize++instance ExpSerialize [Char] where+ exp_serialize = string_serialize++instance ExpSerialize RE where+ exp_serialize _ = string_serialize "RegEx Literal"++-- This instance doesn't overlap with the above three, though GHC's constraint-+-- matching logic obscures that fact. Since a. no other instance is "strictly+-- more specific" and b. this instance is the only incoherent one, the+-- INCOHERENT pragma can be applied safely here without fear of undefined+-- behavior (likely failure) by GHC choosing a random/incorrect instance. See+-- the GHC user's guide at section 10.8.3.6 for more details.+instance {-# INCOHERENT #-} (Num a, Show a) => ExpSerialize a where+ exp_serialize x = toCL $ map CharChunk $ show x++-----------------------------------------------------------------++class LitParse a where+ litParse :: a -> PadsParser ((), Base_md)+ litPrint :: a -> FList++strLit_parseM :: String -> PadsParser ((), Base_md)+strLit_parseM s =+ handleEOF () s $+ handleEOR () s $ do+ match <- scanStrP s+ case match of+ Just [] -> returnClean ()+ Just junk -> returnError () (E.ExtraBeforeLiteral s)+ Nothing -> returnError () (E.MissingLiteral s)++strLit_printFL :: String -> FList+strLit_printFL str = addString str++instance LitParse Char where+ litParse = charLit_parseM+ litPrint = charLit_printFL++charLit_parseM :: Char -> PadsParser ((),Base_md)+charLit_parseM c =+ handleEOF () (mkStr c) $+ handleEOR () (mkStr c) $ do+ c' <- takeHeadP+ if c == c' then returnClean () else do+ foundIt <- scanP c+ returnError () (if foundIt+ then E.ExtraBeforeLiteral (mkStr c)+ else E.MissingLiteral (mkStr c))++charLit_printFL :: Char -> FList+charLit_printFL c = addString [c]++instance LitParse String where+ litParse = strLit_parseM+ litPrint = strLit_printFL+++instance LitParse RE where+ litParse = reLit_parseM+ litPrint = reLit_printFL++reLit_parseM :: RE -> PadsParser ((), Base_md)+reLit_parseM re = do+ (match, md) <- stringME_parseM re+ if numErrors md == 0+ then return ((), md)+ else badReturn ((), md)++reLit_printFL :: RE -> FList+reLit_printFL (RE re) = addString "--REGEXP LITERAL-- "+reLit_printFL (REd re def) = addString def++-- | End of File+type EOF = ()+type EOF_md = Base_md++eof_parseM :: PadsParser (EOF, Base_md)+eof_parseM = do+ isEof <- isEOFP+ if isEof then returnClean ()+ else returnError () (E.ExtraBeforeLiteral "Eof")++-- | End of Record+type EOR = ()+type EOR_md = Base_md++eor_parseM :: PadsParser (EOR, Base_md)+eor_parseM =+ handleEOF () "EOR" $ do+ isEor <- isEORP+ if isEor then doLineEnd+ else returnError () (E.LineError "Expecting EOR")++eor_printFL :: (EOR,Base_md) -> FList+eor_printFL = const eorLit_printFL++eOR_printFL = eor_printFL++eOR_def :: EOR+eOR_def = ()++eof_printFL :: (EOF,Base_md) -> FList+eof_printFL = const eofLit_printFL++eOR_genM :: PadsGen st EOR+eOR_genM = return eOR_def++eOR_serialize :: CList+eOR_serialize = toCL [CharChunk '\n']++eOF_printFL = eof_printFL++eOF_def :: EOF+eOF_def = ()++eOF_genM :: PadsGen st EOF+eOF_genM = return eOF_def++eOF_serialize :: CList+eOF_serialize = toCL []++eorLit_printFL :: FList+eorLit_printFL = printEOR++eofLit_printFL :: FList+eofLit_printFL = printEOF++-----------------------------------------------------------------++newtype Void = Void ()+ deriving (Eq, Show, Data, Typeable, Ord)+type Void_md = Base_md++void_parseM :: PadsParser (Void, Base_md)+void_parseM = returnClean (Void ())++void_def :: Void+void_def = Void ()++type instance Meta Void = Base_md+instance Pads1 () Void Base_md where+ parsePP1 () = void_parseM+ printFL1 () = void_printFL+ def1 () = void_def++void_printFL :: PadsPrinter (Void,Base_md)+void_printFL v = nil++void_genM :: PadsGen st Void+void_genM = return void_def++void_serialize :: CList+void_serialize = toCL []++++pstrLit_printQ :: String -> FList+pstrLit_printQ str = addString str++tuple_printQ :: (String, String, String) -> FList+tuple_printQ (s1,s2,s3) = pstrLit_printQ s1 +++ pstrLit_printQ s2 +++ pstrLit_printQ s3++rtuple_printQ :: (String, String, String) -> FList+rtuple_printQ ss = tuple_printQ ss +++ (addString ['\n'])++list_printQ :: [(String,String,String)] -> FList+list_printQ [] = nil+list_printQ (item:items) = rtuple_printQ item +++ list_printQ items+++++++++----------------------------------++handleEOF val str p+ = do { isEof <- isEOFP+ ; if isEof then+ returnError val (E.FoundWhenExpecting "EOF" str)+ else p}++handleEOR val str p+ = do { isEor <- isEORP+ ; if isEor then+ returnError val (E.FoundWhenExpecting "EOR" str)+ else p}++checkEOF val str p+ = do { isEof <- isEOFP+ ; if isEof then+ returnClean val+ else p}++checkEOR val str p+ = do { isEor <- isEORP+ ; if isEor then+ returnClean val+ else p}++----------------------------------+-- BINARY TYPES --+----------------------------------+++type Bytes = S.RawStream+type Bytes_md = Base_md++bytes_parseM :: Int -> PadsParser (Bytes,Bytes_md)+bytes_parseM n =+ handleEOF (def1 n) "Bytes" $+ handleEOR (def1 n) "Bytes" $ do+ bytes <- takeBytesP n+ if B.length bytes == n+ then returnClean bytes+ else returnError (def1 n) (E.Insufficient (B.length bytes) n)++bytes_printFL :: Int -> PadsPrinter (Bytes, Bytes_md)+bytes_printFL n (bs, bmd) =+ addBString bs++bytes_def :: Int -> Bytes+bytes_def i = B.pack $ replicate i (0::Word8)++bytes_genM :: Int -> PadsGen st Bytes+bytes_genM i = do+ w8s <- replicateM i $ randNumBound (255 :: Word8)+ return $ B.pack w8s++bytes_serialize :: Int -> Bytes -> CList+bytes_serialize _ bs = toCL $ map (CharChunk . S.word8ToChr) $ B.unpack bs++type instance PadsArg Bytes = Int+type instance Meta Bytes = Bytes_md+instance Pads1 Int Bytes Bytes_md where+ parsePP1 = bytes_parseM+ printFL1 = bytes_printFL+ def1 i = bytes_def i+++{- Helper functions -}+mkStr c = "'" ++ [c] ++ "'"++-- | Some PADS types, PConstrain for instance, are designed to have access to+-- parsed metadata, stored as the variable md. In parsing, metadata is created+-- and supplied to the constraint at the correct time in the generated parsing+-- functions.+-- However, during generation of generation functions, no metadata exists.+-- Providing this variable assignment prevents compile time errors of functions+-- with predicates that refer to md, and is safe wrt parsing predicates+-- because the md variables in their generated code are bound in lambdas.+md = Base_md 0 Nothing
@@ -0,0 +1,77 @@+{-# LANGUAGE NamedFieldPuns, DeriveDataTypeable #-}+{-# OPTIONS_HADDOCK prune #-} +{-|+ Module : Language.Pads.Errors+ Description : Parse error reporting support+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental+-}++module Language.Pads.Errors where+import Text.PrettyPrint.Mainland as PP+import Text.PrettyPrint.Mainland.Class+import qualified Language.Pads.Source as S+import Data.Data++-- | Errors which can be encountered at runtime when parsing a Pads type+data ErrMsg =+ FoundWhenExpecting String String+ | MissingLiteral String+ | ExtraBeforeLiteral String+ | LineError String+ | Insufficient Int Int+ | RegexMatchFail String+ | TransformToDstFail String String String+ | TransformToSrcFail String String String+ | UnderlyingTypedefFail+ | PredicateFailure+ | ExtraStuffBeforeTy String String+ | FileError String String+ | BitWidthError Int Int+ deriving (Typeable, Data, Eq, Ord, Show)++{- XXX-KSF: fix pretty printing to use pretty printing combinators rather than string ++ -}+-- | Pretty printer for Pads runtime error messages.+instance Pretty ErrMsg where+ ppr (FoundWhenExpecting str1 str2) = text ("Encountered " ++ str1 ++ " when expecting " ++ str2 ++ ".")+ ppr (MissingLiteral s) = text ("Missing Literal: " ++ s ++ ".")+ ppr (ExtraBeforeLiteral s) = text ("Extra bytes before literal: " ++ s ++ ".")+ ppr (ExtraStuffBeforeTy junk ty) = text ("Extra bytes: " ++ junk ++ " before " ++ ty ++ ".")+ ppr (Insufficient found expected) = text("Found " ++ show found ++ " bytes when looking for " ++ show expected ++ "bytes.")+ ppr (RegexMatchFail s) = text ("Failed to match regular expression: " ++ s ++ ".")+ ppr (TransformToDstFail s1 s2 s3) = text ("Parsing transform " ++ s1 ++ " failed on input: " ++ s2 ++ s3)+ ppr (TransformToSrcFail s1 s2 s3) = text ("Printing transform "++ s1 ++ " failed on input: " ++ s2 ++ s3)+ ppr (LineError s) = text s+ ppr UnderlyingTypedefFail = text "Pads predicate is true, but underlying type had an error."+ ppr PredicateFailure = text "Pads predicate is false."+ ppr (FileError err file) = text ("Problem with file: " ++ file ++ "("++ err ++ ").")+ ppr (BitWidthError x y) = text ("Bad field width: " ++ show y ++ " cannot fit in " ++ show x ++ ".")++-- | Error information relating back to the source input+data ErrInfo = ErrInfo { msg :: ErrMsg,+ position :: Maybe S.Span }+ deriving (Typeable, Data, Eq, Ord, Show)++-- | Pretty printer for reporting where in the source text a parse error+-- occured.+instance Pretty ErrInfo where+ ppr ErrInfo{msg,position} = ppr msg <+>+ case position of+ Nothing -> empty+ Just pos -> text "at:" <+> ppr pos++-- | Always just pick the first error message+mergeErrInfo ErrInfo{msg=msg1, position=position1} ErrInfo{msg=msg2, position=position2} =+ ErrInfo{msg=msg1, position=position1}++-- | Merge errors in the Maybe monad+maybeMergeErrInfo m1 m2 = case (m1,m2) of+ (Nothing,Nothing) -> Nothing+ (Just p, Nothing) -> Just p+ (Nothing, Just p) -> Just p+ (Just p1, Just p2) -> Just (mergeErrInfo p1 p2)+
@@ -0,0 +1,267 @@+{-# LANGUAGE TypeSynonymInstances, TemplateHaskell, QuasiQuotes, MultiParamTypeClasses+ , FlexibleInstances, DeriveDataTypeable, NamedFieldPuns, ScopedTypeVariables #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.GenPretty+ Description : Template haskell based pretty printing instances+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.GenPretty where++import Language.Pads.Padsc+import Language.Pads.Errors+import Language.Pads.MetaData+import Language.Pads.TH++import Language.Haskell.TH as TH hiding (ppr)++import Text.PrettyPrint.Mainland+import Text.PrettyPrint.Mainland.Class++import qualified Data.List as L+import qualified Data.Set as S+import Control.Monad++import System.Posix.Types+import Data.Word+import Data.Int+import Data.Time+import Debug.Trace as D++pprE argE = AppE (VarE 'ppr) argE+pprListEs argEs = ListE (map pprE argEs)+pprCon1E argE = AppE (VarE 'pprCon1) argE+pprCon2E argE = AppE (VarE 'pprCon2) argE++pprCon1 arg = ppr (toList1 arg)+pprCon2 arg = ppr (toList2 arg)++-- | Get all the names of types referenced within the given 'TH.Type'+getTyNames :: TH.Type -> S.Set TH.Name+getTyNames ty = case ty of+ ForallT tvb cxt ty' -> getTyNames ty'+ VarT name -> S.empty+ ConT name -> S.singleton name+ TupleT i -> S.empty+ ArrowT -> S.empty+ ListT -> S.empty+ AppT t1 t2 -> getTyNames t1 `S.union` getTyNames t2+ SigT ty kind -> getTyNames ty++-- | Get all the types referenced within the given Haskell constructor.+getTyNamesFromCon :: TH.Con -> S.Set TH.Name+getTyNamesFromCon con = case con of+ (NormalC name stys) -> S.unions (map (\(_,ty) -> getTyNames ty) stys)+ (RecC name vstys) -> S.unions (map (\(_,_,ty) -> getTyNames ty) vstys)+ (InfixC st1 name st2) -> getTyNames (snd st1) `S.union` getTyNames (snd st2)+ (ForallC tvb cxt con) -> getTyNamesFromCon con++-- | Recursively reify types to get all the named types referenced by the given+-- name+getNamedTys :: TH.Name -> Q [TH.Name]+getNamedTys ty_name = S.toList <$> getNamedTys' S.empty (S.singleton ty_name)++-- | Helper for 'getNamedTys'+getNamedTys' :: S.Set TH.Name -> S.Set TH.Name -> Q (S.Set TH.Name)+getNamedTys' answers worklist =+ if S.null worklist then return answers+ else do+ { let (ty_name, worklist') = S.deleteFindMin worklist+ ; let answers' = S.insert ty_name answers+ ; info <- reify ty_name+ ; case info of+ TyConI (NewtypeD [] ty_name' [] _ con derives) -> do+ { let all_nested = getTyNamesFromCon con+ ; let new_nested = all_nested `S.difference` answers'+ ; let new_worklist = worklist' `S.union` new_nested+ ; getNamedTys' answers' new_worklist+ }+ TyConI (DataD [] ty_name' [] _ cons derives) -> do+ { let all_nested = S.unions (map getTyNamesFromCon cons)+ ; let new_nested = all_nested `S.difference` answers'+ ; let new_worklist = worklist' `S.union` new_nested+ ; getNamedTys' answers' new_worklist+ }+ TyConI (TySynD _ _ _ ) -> do {reportError ("getTyNames: unimplemented TySynD case " ++ (nameBase ty_name)); return answers'}+ TyConI (ForeignD _) -> do {reportError ("getTyNames: unimplemented ForeignD case " ++ (nameBase ty_name)); return answers'}+ PrimTyConI _ _ _ -> return answers+ otherwise -> do {reportError ("getTyNames: pattern didn't match for " ++ (nameBase ty_name)); return answers'}+ }++-- | All the base types supported by Pads+baseTypeNames = S.fromList [ ''Int, ''Char, ''Digit, ''Text, ''String, ''StringFW, ''StringME+ , ''StringSE, ''COff, ''EpochTime, ''FileMode, ''Int, ''Word, ''Int64+ , ''Language.Pads.Errors.ErrInfo, ''Bool, ''Binary, ''Base_md, ''UTCTime, ''TimeZone+ ]++-- | Recursively make the pretty printing instance for a given named type by+-- also making instances for all nested types.+mkPrettyInstance :: TH.Name -> Q [TH.Dec]+mkPrettyInstance ty_name = mkPrettyInstance' (S.singleton ty_name) baseTypeNames []++mkMe :: TH.Name -> Q [TH.Dec]+mkMe n = do+ D.traceM "HELLOOOOOOOOOO"+ return []++-- | Helper for 'mkPrettyInstance'+mkPrettyInstance' :: S.Set TH.Name -> S.Set TH.Name -> [TH.Dec] -> Q [TH.Dec]+mkPrettyInstance' worklist done decls =+ if S.null worklist then return decls+ else do+ let (ty_name, worklist') = S.deleteFindMin worklist+ if ty_name `S.member` done then mkPrettyInstance' worklist' done decls+ else do+ let tyBaseName = nameBase ty_name+ let baseStr = strToLower tyBaseName+ let specificPprName = mkName (baseStr ++ "_ppr")+ let funName = mkName (strToLower (tyBaseName ++ "_ppr"))+ let inst = AppT (ConT ''Pretty) (ConT ty_name)+ let genericPprName = mkName "ppr"+ let ppr_method = ValD (VarP genericPprName) (NormalB (VarE specificPprName)) []+ let instD = InstanceD Nothing [] inst [ppr_method]+ let newDone = S.insert ty_name done+ info <- reify ty_name+ (nestedTyNames, decls') <- case info of+ TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT ListT ty)]) derives) -> do -- List+ { let nestedTyNames = getTyNames ty+-- ; reportError ("list case " ++ (nameBase ty_name))+ ; (itemsE,itemsP) <- doGenPE "list"+ ; let mapE = AppE (AppE (VarE 'map) (VarE 'ppr)) itemsE+ ; let bodyE = AppE (AppE (VarE 'namedlist_ppr) (nameToStrLit ty_name)) mapE+ ; let argP = ConP (mkName tyBaseName) [itemsP]+ ; let clause = Clause [argP] (NormalB bodyE) []+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]])+ }+ TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT (AppT (ConT ty_con_name) ty_arg1) ty_arg2) ]) derives) -> do -- curry rep (Map)+ { let nestedTyNames = getTyNames ty_arg2+ ; (argP, body) <- mkPatBody tyBaseName pprCon2E+-- ; reportError ("curry rep case " ++ (nameBase ty_name))+ ; let clause = Clause [argP] body []+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]])+ }+ TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, AppT (ConT ty_con_name) ty_arg) ]) derives) -> do -- con rep (Set)+ { let nestedTyNames = getTyNames ty_arg+ ; (argP, body) <- mkPatBody tyBaseName pprCon1E+-- ; reportError ("con rep case " ++ (nameBase ty_name))+ ; let clause = Clause [argP] body []+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]])+ }+ TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, ConT core_name)]) derives) -> do -- App, Typedef+ { (argP, body) <- mkPatBody tyBaseName pprE+-- ; reportError ("app, typedef case " ++ (nameBase ty_name))+ ; let clause = Clause [argP] body []+ ; return (S.singleton core_name, [instD, FunD specificPprName [clause]])+ }+ TyConI (NewtypeD [] ty_name' [] _ (NormalC ty_name'' [(Bang NoSourceUnpackedness NoSourceStrictness, ty)]) derives) | isTuple ty -> do -- Tuple+ { let nestedTyNames = getTyNames ty+-- ; reportError ("tuple case " ++ (nameBase ty_name))+ ; let (len, tys) = tupleTyToListofTys ty+ ; (exps, pats) <- doGenPEs len "tuple"+ ; let bodyE = AppE (AppE (VarE 'namedtuple_ppr) (LitE (StringL tyBaseName))) (pprListEs exps)+ ; let argP = ConP (mkName tyBaseName) [TupP pats]+ ; let clause = Clause [argP] (NormalB bodyE) []+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]])+ }+ TyConI (DataD [] ty_name' [] _ cons derives) | isDataType cons -> do+ { let nestedTyNames = S.unions (map getTyNamesFromCon cons)+ ; (exp, pat) <- doGenPE "case_arg"+ ; matches <- mapM mkClause cons+ ; let caseE = CaseE exp matches+ ; let clause = Clause [pat] (NormalB caseE) []+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]] )+ }+ TyConI (DataD [] ty_name' [] _ cons derives) | isRecordType cons -> do+ { let nestedTyNames = S.unions (map getTyNamesFromCon cons)+-- ; report (length cons /= 1) ("GenPretty: record " ++ (nameBase ty_name') ++ " did not have a single constructor.")+ ; clause <- mkRecord (L.head cons)+ ; return (nestedTyNames, [instD, FunD specificPprName [clause]])+ }+ TyConI (DataD _ ty_name' _ _ cons derives) -> do+ {+-- reportError ("DataD pattern didn't match for"++(nameBase ty_name))+ ; return (S.empty, [])}+ TyConI (TySynD ty_name' [] ty) -> do+ { let nestedTyNames = getTyNames ty+-- ; reportError ("tysyn for"++(nameBase ty_name))+ ; return (nestedTyNames, [])}+ TyConI (TySynD ty_name' tyVarBndrs ty) -> do+ { let nestedTyNames = getTyNames ty+-- ; reportError ("tysyn for"++(nameBase ty_name))+ ; return (nestedTyNames, [])}+ TyConI dec -> do {reportError ("otherwise; tyconI case "++(nameBase ty_name)) ; return (S.empty, [])}+ otherwise -> do {reportError ("pattern didn't match for "++(nameBase ty_name)) ; return (S.empty, [])}+ let newWorklist = worklist `S.union` nestedTyNames+ let newDecls = decls'++decls+ mkPrettyInstance' newWorklist newDone newDecls++-- | Is the given type a TupleT?+isTuple (TupleT n) = True+isTuple (AppT ty _) = isTuple ty++-- | Is the given constructor a normal Haskell constructor?+isDataType [] = False+isDataType (NormalC _ _ : rest) = True+isDataType _ = False++-- | Is the given constructor a Haskell record constructor?+isRecordType [] = False+isRecordType (RecC _ _ : rest) = True+isRecordType _ = False++-- | Make the pattern body of a pretty printer expression for a named Pads type+mkPatBody core_name_str pprE = do+ (exp,pat) <- doGenPE "arg"+ bodyE <- [| namedty_ppr $(litE $ stringL core_name_str) $(return $ pprE exp) |]+ argP <- conP (mkName core_name_str) [return pat]+ return (argP, NormalB bodyE)++-- | Make the pattern body of a pretty printer expression for a Pads type /+-- data constructor without arguments.+mkPatBodyNoArg core_name_str = do+ bodyE <- [| text $(litE $ stringL core_name_str) |]+ argP <- conP (mkName core_name_str) []+ return (argP, NormalB bodyE)++-- | Make the clause for the data constructor of a data type based on whether or+-- not it has any arguments.+mkClause con = case con of+ NormalC name [] -> do+ { (argP, body) <- mkPatBodyNoArg (nameBase name)+ ; return (Match argP body [])+ }+ NormalC name ty_args -> do+ { (argP, body) <- mkPatBody (nameBase name) pprE+ ; return (Match argP body [])+ }+ otherwise -> error "mkClause not implemented for this kind of constructor."++-- | Make the Haskell clause for a Pads record.+mkRecord (RecC rec_name fields) = do+ fieldInfo <- mapM mkField fields+ let (recPs, recEs) = unzip fieldInfo+ let recP = RecP rec_name recPs+ let bodyE = AppE (AppE (VarE 'record_ppr) (nameToStrLit rec_name)) (ListE recEs)+ return (Clause [recP] (NormalB bodyE) [])++-- | Make the field pretty printer case.+mkField (field_name, _, ty) = do+ (expE, pat) <- doGenPE (nameBase field_name)+ fieldE <- [| field_ppr $(return $ nameToStrLit field_name) $(return $ pprE expE) |]+ return ((field_name, pat), fieldE)++nameToStrLit name = LitE (StringL (nameBase name))++-- instance Pretty a => Pretty (PMaybe a) where+-- ppr PNothing = text ""+-- ppr (PJust a) = ppr a+--+-- instance Pretty a => Pretty (PMaybe_imd a) where+-- ppr (PNothing_imd _) = text ""+-- ppr (PJust_imd a) = ppr a
@@ -0,0 +1,139 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveFunctor, FlexibleContexts, FlexibleInstances+ , MultiParamTypeClasses, DerivingVia, InstanceSigs #-}++module Language.Pads.Generation where++import Control.Monad.IO.Class (liftIO)+import Data.List (delete)+import GHC.Prim (RealWorld)+import System.Random.MWC++import Control.Monad.Trans.Class (lift)+import Control.Monad.State.Lazy++-- | A custom application of the ReaderT monad, allowing threaded access to a+-- random generator, supplied when the generation function is called at top+-- level (i.e. via runPadsGen)+newtype PadsGen st a = PadsGen { unPadsGen :: StateT (GenIO, st) IO a }+ -- Here 'Gen RealWorld' is equal to 'GenIO' above. We can't write+ -- 'GenIO' here because 'GenIO' is defined as 'Gen (PrimState IO)',+ -- 'PrimState' is a type family, and type family instances aren't+ -- allowed. It's probably a bug, but GHC will allow us to derive a+ -- @MonadReader GenIO@ instance here, but we then get type errors at+ -- use sites of 'MonadReader' functions, e.g. 'ask'.+ deriving (Functor, Applicative, Monad, MonadIO)++instance MonadState (Gen RealWorld, st) (PadsGen st) where+ get :: PadsGen st (Gen RealWorld, st)+ get = PadsGen $ StateT $ \s -> pure (s,s)+ + put :: (Gen RealWorld, st) -> PadsGen st ()+ put s = PadsGen $ StateT $ \_ -> pure ((), s)++askGen :: MonadState (GenIO, st) (PadsGen st) => (GenIO -> PadsGen st a) -> PadsGen st a+askGen fncn = get >>= fncn . fst++-- | Provides the requisite random number generator to the supplied generation+-- computation and returns the result as a value in IO. Initial generator state+-- must be given.+runPadsGenSt :: st -> PadsGen st a -> IO a+runPadsGenSt init_st genM = do+ gen <- createSystemRandom+ fst <$> runStateT (unPadsGen genM) (gen, init_st)++-- | Pull user-level state out of the generator (ignore the random seed).+getState :: PadsGen st st+getState = do+ (_, st) <- get+ return st++-- | Put user-level state intothe generator (carrying over the random seed).+putState :: st -> PadsGen st ()+putState v = do+ (g, _) <- get+ put (g, v)++-- | Delegates to 'runPadsGen\''+runPadsGen :: PadsGen () a -> IO a+runPadsGen = runPadsGenSt ()++-- | The types 'randNum'/'randNumBound'/'randNumBetween' return are dictated by+-- the types of their callers.+randNum :: (Variate a) => PadsGen st a+randNum = askGen $ (liftIO . uniform)++-- | A number with bounds i and j+randNumBetween :: (Integral a, Variate a) => a -> a -> PadsGen st a+randNumBetween i j = askGen $ (liftIO . (uniformR (i, j)))++-- | A number with an upper bound i+randNumBound :: (Integral a, Variate a) => a -> PadsGen st a+randNumBound i = randNumBetween 0 i++-- | As they aren't members of the System.Random.MWC class Variate, Integers+-- require special treatment - convert them from doubles.+randInteger :: PadsGen st Integer+randInteger = randIntegerBound (2^1023)++-- | See randInteger+randIntegerBound :: Integral a => a -> PadsGen st Integer+randIntegerBound i = do+ (gen,_) <- get+ i' <- liftIO $ uniformR (0 :: Double, (fromIntegral i) :: Double) gen+ (return . toInteger . floor) i'++-- | Choose an element from a list at random+randElem :: [a] -> PadsGen st a+randElem xs = do+ (gen,_) <- get+ r <- liftIO $ fromIntegral <$> uniformR (0, length xs - 1) gen+ return $ xs !! r++-- | A random letter from English upper and lowercase letters+randLetter :: PadsGen st Char+randLetter = randElem letters++-- | A random letter from English upper and lowercase letters, excluding the+-- provided character+randLetterExcluding :: Char -> PadsGen st Char+randLetterExcluding c = randElem (delete c letters)++letters :: [Char]+letters = ['A'..'Z'] ++ ['a'..'z']++listLengthLimit = 100++-- | A list of random length, provided a PadsGen generator. Optionally also+-- paramaterized by an Int, which if provided will be the length of the list+randList :: PadsGen st a -> Maybe Int -> PadsGen st [a]+randList padsGen intM = do+ i <- case intM of+ Just x -> return x+ Nothing -> askGen $ (liftIO . (uniformR (1, listLengthLimit)))+ replicateM i padsGen++recLimit = 10000++-- | Provided a predicate, function that transforms a seed value, recursion+-- limit, and seed value, generates a value of the seed's type that satisfies+-- the predicate+untilM :: Monad m => (a -> Bool) -> (a -> m a) -> Integer -> a -> m a+untilM p f i z = do+ when (i <= 0)+ (error $ "untilM: recursion too deep. Your description probably "+ ++ "contains a too-narrow constraint to efficiently "+ ++ "generate data that satisfy it. To increase "+ ++ "the recursion limit ('recLimit' in Generation.hs), "+ ++ "currently set to " ++ show recLimit+ ++ ", edit it and try again.")+ if p z+ then return z+ else f z >>= untilM p f (i - 1)++-- | A random instance of the provided PadsGen that satisfies the provided+-- constraint+randWithConstraint :: PadsGen st a -> (a -> Bool) -> PadsGen st a+randWithConstraint padsGen pred = do+ x <- padsGen+ x' <- untilM pred (const padsGen) recLimit x+ return x'
@@ -0,0 +1,203 @@+{-# LANGUAGE TypeFamilies, ConstraintKinds, MultiParamTypeClasses+ , FunctionalDependencies, ScopedTypeVariables, FlexibleContexts+ , Rank2Types, FlexibleInstances #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Generic+ Description : Default parse values using GHC Generics+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Generic where++import Language.Pads.MetaData+import Language.Pads.PadsParser+import qualified Language.Pads.Errors as E+import qualified Language.Pads.Source as S+import Language.Pads.PadsPrinter+import qualified Data.ByteString as B+import qualified Control.Exception as CE+import Data.Data+import Data.Generics.Aliases (extB, ext1B)+import Data.Map (Map(..))+import qualified Data.Map as Map+import Data.Set (Set(..))+import qualified Data.Set as Set+import Language.Pads.Errors++import System.Posix.Types+import Foreign.C.Types+import System.CPUTime++type Pads rep md = Pads1 () rep md++def :: Pads rep md => rep+def = def1 ()+defaultMd :: Pads rep md => rep -> md+defaultMd = defaultMd1 ()+parsePP :: Pads rep md => PadsParser (rep,md)+parsePP = parsePP1 ()+printFL :: Pads rep md => PadsPrinter (rep,md)+printFL = printFL1 ()+defaultRepMd :: Pads rep md => (rep,md)+defaultRepMd = defaultRepMd1 ()++parseRep :: Pads rep md => String -> rep+parseRep cs = fst $ fst $ parseStringInput parsePP cs++parseS :: Pads rep md => String -> ((rep, md), String)+parseS cs = parseStringInput parsePP cs++parseBS :: Pads rep md => B.ByteString -> ((rep, md), B.ByteString)+parseBS cs = parseByteStringInput parsePP cs++parseFile :: Pads rep md => FilePath -> IO (rep, md)+parseFile file = parseFileWith parsePP file++parseFileWithDisc :: Pads rep md => S.RecordDiscipline -> FilePath -> IO (rep, md)+parseFileWithDisc d file = parseFileWithD d parsePP file++printS :: Pads rep md => (rep,md) -> (String)+printS = S.byteStringToStr . printBS++printRep :: Pads rep md => rep -> String+printRep = printRep1 ()++printBS :: Pads rep md => (rep,md) -> (B.ByteString)+printBS r = let f = (printFL r) in f B.empty++printFile :: Pads rep md => FilePath -> (rep,md) -> IO ()+printFile filepath r = do+ let str = printBS r+ B.writeFile filepath str++printFileRep :: Pads rep md => FilePath -> rep -> IO ()+printFileRep filepath r = printFile filepath (r,defaultMd r)++type family PadsArg rep :: *++class (Data rep, PadsMD md, PadsMD (Meta rep)) => Pads1 arg rep md | rep -> md, rep -> arg where+ def1 :: arg -> rep+ def1 = \_ -> gdef+ defaultMd1 :: arg -> rep -> md+ defaultMd1 _ _ = myempty+ parsePP1 :: arg -> PadsParser (rep,md)+ printFL1 :: arg -> PadsPrinter (rep,md)+ defaultRepMd1 :: arg -> (rep,md)+ defaultRepMd1 arg = (rep,md) where+ rep = def1 arg+ md = defaultMd1 arg rep++parseRep1 :: Pads1 arg rep md => arg -> String -> rep+parseRep1 arg cs = fst $ fst $ parseStringInput (parsePP1 arg) cs++parseS1 :: Pads1 arg rep md => arg -> String -> ((rep, md), String)+parseS1 arg cs = parseStringInput (parsePP1 arg) cs++parseBS1 :: Pads1 arg rep md => arg -> B.ByteString -> ((rep, md), B.ByteString)+parseBS1 arg cs = parseByteStringInput (parsePP1 arg) cs+++parseString1 :: Pads1 arg rep md => arg-> String -> (rep, md)+parseString1 arg str = parseStringWith (parsePP1 arg) str++parseFile1 :: Pads1 arg rep md => arg-> FilePath -> IO (rep, md)+parseFile1 arg file = parseFileWith (parsePP1 arg) file++parseFile1WithDisc :: Pads1 arg rep md => S.RecordDiscipline -> arg -> FilePath -> IO (rep, md)+parseFile1WithDisc d arg file = parseFileWithD d (parsePP1 arg) file++printS1 :: Pads1 arg rep md => arg -> (rep,md) -> (String)+printS1 arg (rep,md) = S.byteStringToStr (printBS1 arg (rep,md))++printRep1 :: Pads1 arg rep md => arg -> rep -> String+printRep1 arg rep = printS1 arg (rep,defaultMd1 arg rep)++printBS1 :: Pads1 arg rep md => arg -> (rep,md) -> (B.ByteString)+printBS1 arg r = let f = (printFL1 arg r) in f B.empty+printFile1 :: Pads1 arg rep md => arg -> FilePath -> (rep,md) -> IO ()+printFile1 arg filepath r = do+ let str = printBS1 arg r+ B.writeFile filepath str++printFileRep1 :: Pads1 arg rep md => arg -> FilePath -> rep -> IO ()+printFileRep1 arg filepath r = printFile1 arg filepath (r,defaultMd1 arg r)++parseStringWith :: (Data rep, PadsMD md) => PadsParser (rep,md) -> String -> (rep,md)+parseStringWith p str = fst $ parseStringInput p str++parseFileWith :: (Data rep, PadsMD md) => PadsParser (rep,md) -> FilePath -> IO (rep,md)+parseFileWith p file = do+ result <- CE.try (parseFileInput p file)+ case result of+ Left (e::CE.SomeException) -> return (gdef, replace_md_header gdef+ (mkErrBasePD (E.FileError (show e) file) Nothing))+ Right r -> return r++parseFileWithD :: (Data rep, PadsMD md) => S.RecordDiscipline -> PadsParser (rep,md) -> FilePath -> IO (rep,md)+parseFileWithD d p file = do+ result <- CE.try (parseFileInputWithDisc d p file)+ case result of+ Left (e::CE.SomeException) -> return (gdef, replace_md_header gdef+ (mkErrBasePD (E.FileError (show e) file) Nothing))+ Right r -> return r++{- Generic function for computing the default for any type supporting Data a interface -}+getConstr :: DataType -> Constr+getConstr ty =+ case dataTypeRep ty of+ AlgRep cons -> head cons+ IntRep -> mkIntegralConstr ty 0+ FloatRep -> mkRealConstr ty 0.0+ CharRep -> mkCharConstr ty '\NUL'+ NoRep -> error "PADSC: Unexpected NoRep in PADS type"++gdef :: Data a => a+gdef = def_help+ where+ def_help+ = let ty = dataTypeOf (def_help)+ constr = getConstr ty+ in fromConstrB gdef constr++ext2 :: (Data a, Typeable t)+ => c a+ -> (forall d1 d2. (Data d1, Data d2) => c (t d1 d2))+ -> c a+ext2 def ext = maybe def id (dataCast2 ext)++newtype B x = B {unB :: x}++ext2B :: (Data a, Typeable t)+ => a+ -> (forall b1 b2. (Data b1, Data b2) => t b1 b2)+ -> a+ext2B def ext = unB ((B def) `ext2` (B ext))++++class BuildContainer2 c key item where+ buildContainer2 :: [(key,item)] -> c key item+ toList2 :: c key item -> [(key,item)]++instance Ord key => BuildContainer2 Map key a where+ buildContainer2 = Map.fromList+ toList2 = Map.toList++class BuildContainer1 c key item where+ buildContainer1 :: [(key,item)] -> c (key, item)+ toList1 :: c (key, item) -> [(key,item)]++instance (Ord a,Ord key) => BuildContainer1 Set key a where+ buildContainer1 = Set.fromList+ toList1 = Set.toList++instance BuildContainer1 [] key a where+ buildContainer1 = id+ toList1 = id+
@@ -0,0 +1,84 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,+ FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}+{-# OPTIONS_HADDOCK prune, ignore-exports #-}+{-|+ Module : Language.Pads.Library.BigEndian+ Description : Support for parsing of big endian data+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Library.BigEndian where++import Language.Pads.Padsc+import Language.Pads.Library.BinaryUtilities++import qualified Data.Int+import qualified Data.Word+import Data.ByteString as B++-- * Signed Integers+-- | type Int8 : 8-bit, signed integers+type Int8 = Data.Int.Int8+[pads| obtain Int8 from Bytes 1 using <|(bToi8sbh,i8Tobsbh)|> |]+bToi8sbh :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)+bToi8sbh p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)+i8Tobsbh (i,md) = (B.singleton (fromIntegral i), md)++int8_genM :: PadsGen st Int8+int8_genM = randNum+++-- | type Int16 : signed byte high, 16-bit, signed integers+type Int16 = Data.Int.Int16+[pads| obtain Int16 from Bytes 2 using <| (bToi16sbh,i16sbhTob) |> |]+bToi16sbh p (bs,md) = (bytesToInt16 SBH bs, md)+i16sbhTob (i,md) = (int16ToBytes SBH i, md)++int16_genM :: PadsGen st Int16+int16_genM = randNum+++-- | type Int32 : signed byte high, 32-bit, signed integers+type Int32 = Data.Int.Int32+[pads| obtain Int32 from Bytes 4 using <| (bToi32sbh,i32sbhTob) |> |]+bToi32sbh p (bs,md) = (bytesToInt32 SBH bs, md)+i32sbhTob (i,md) = (int32ToBytes SBH i, md)++int32_genM :: PadsGen st Int32+int32_genM = randNum+++-- * Unsigned Integers (aka Words)+-- | type Word8 : signed byte high, 8-bit, unsigned integers+type Word8 = Data.Word.Word8+[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]+bTow8 p (bytes,md) = (bytes `B.index` 0, md)+w8Tob (i,md) = (B.singleton i, md)++word8_genM :: PadsGen st Word8+word8_genM = randNum+++-- | type Word16 : signed byte high, 16-bit, unsigned integers+type Word16 = Data.Word.Word16+[pads| obtain Word16 from Bytes 2 using <| (bTow16sbh,w16sbhTob) |> |]+bTow16sbh p (bs,md) = (bytesToWord16 SBH bs, md)+w16sbhTob (i,md) = (word16ToBytes SBH i, md)++word16_genM :: PadsGen st Word16+word16_genM = randNum+++-- | type Word32 : signed byte high, 32-bit, unsigned integers+type Word32 = Data.Word.Word32+[pads| obtain Word32 from Bytes 4 using <| (bTow32sbh,w32sbhTob) |> |]+bTow32sbh p (bs,md) = (bytesToWord32 SBH bs, md)+w32sbhTob (i,md) = (word32ToBytes SBH i, md)++word32_genM :: PadsGen st Word32+word32_genM = randNum
@@ -0,0 +1,114 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,+ FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Library.BinaryUtilities+ Description : Utilities for transforming binary data+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Library.BinaryUtilities where++import Data.Int+import Data.Word+import Data.ByteString as B+import Data.Bits+import System.ByteOrder++-------------------------------------------------------------------------------++-- | * Signed-Byte-High Functions+-- The most significant digit is on the left (lowest address).+-- These functions manage the case where the wire representation+-- is signed-byte high, regardless of the endianness of the host+-- machine.+data Endian = SBH | SBL | Native++bytesToInt16 :: Endian -> B.ByteString -> Int16+bytesToInt16 endian = fromIntegral . (bytesToWord16 endian)++int16ToBytes :: Endian -> Int16 -> B.ByteString+int16ToBytes endian = (word16ToBytes endian) . fromIntegral+++bytesToInt32 :: Endian -> B.ByteString -> Int32+bytesToInt32 endian = fromIntegral . (bytesToWord32 endian)++int32ToBytes :: Endian -> Int32 -> B.ByteString+int32ToBytes endian = (word32ToBytes endian) . fromIntegral+++bytesToWord16 :: Endian -> B.ByteString -> Word16+bytesToWord16 endian b =+ let b0 :: Word16 = fromIntegral (b `B.index` 0)+ b1 :: Word16 = fromIntegral (b `B.index` 1)+ in+ case (endian, byteOrder) of+ (SBH, BigEndian) -> assembleWord16 (b1, b0)+ (SBH, LittleEndian) -> assembleWord16 (b0, b1)+ (SBL, BigEndian) -> assembleWord16 (b0, b1)+ (SBL, LittleEndian) -> assembleWord16 (b1, b0)+ (Native, BigEndian) -> assembleWord16 (b0, b1)+ (Native, LittleEndian) -> assembleWord16 (b1, b0)+++word16ToBytes :: Endian -> Word16 -> B.ByteString+word16ToBytes endian word16 =+ let w0 :: Word8 = fromIntegral (shiftR (word16 .&. 0xFF00) 8)+ w1 :: Word8 = fromIntegral (word16 .&. 0x00FF)+ in case (endian, byteOrder) of+ (SBH, BigEndian) -> B.pack [w1,w0]+ (SBH, LittleEndian) -> B.pack [w0,w1]+ (SBL, BigEndian) -> B.pack [w0,w1]+ (SBL, LittleEndian) -> B.pack [w1,w0]+ (Native, BigEndian) -> B.pack [w0,w1]+ (Native, LittleEndian) -> B.pack [w1,w0]+++assembleWord16 :: (Word16, Word16) -> Word16+assembleWord16 (b0, b1) = shift b0 8 .|. b1++++bytesToWord32 :: Endian -> B.ByteString -> Word32+bytesToWord32 endian b =+ let b0 :: Word32 = fromIntegral (b `B.index` 0)+ b1 :: Word32 = fromIntegral (b `B.index` 1)+ b2 :: Word32 = fromIntegral (b `B.index` 2)+ b3 :: Word32 = fromIntegral (b `B.index` 3)+ in+ case (endian, byteOrder) of+ (SBH, BigEndian) -> assembleWord32 (b3, b2, b1, b0)+ (SBH, LittleEndian) -> assembleWord32 (b0, b1, b2, b3)+ (SBL, BigEndian) -> assembleWord32 (b0, b1, b2, b3)+ (SBL, LittleEndian) -> assembleWord32 (b3, b2, b1, b0)+ (Native, BigEndian) -> assembleWord32 (b0, b1, b2, b3)+ (Native, LittleEndian) -> assembleWord32 (b3, b2, b1, b0)+++word32ToBytes :: Endian -> Word32 -> B.ByteString+word32ToBytes endian word32 =+ let w0 :: Word8 = fromIntegral (shiftR (word32 .&. 0xFF000000) 24)+ w1 :: Word8 = fromIntegral (shiftR (word32 .&. 0x00FF0000) 16)+ w2 :: Word8 = fromIntegral (shiftR (word32 .&. 0x0000FF00) 8)+ w3 :: Word8 = fromIntegral (word32 .&. 0x000000FF)+ in case (endian, byteOrder) of+ (SBH, BigEndian) -> B.pack [w3,w2,w1,w0]+ (SBH, LittleEndian) -> B.pack [w0,w1,w2,w3]+ (SBL, BigEndian) -> B.pack [w0,w1,w2,w3]+ (SBL, LittleEndian) -> B.pack [w3,w2,w1,w0]+ (Native, BigEndian) -> B.pack [w0,w1,w2,w3]+ (Native, LittleEndian) -> B.pack [w3,w2,w1,w0]+++assembleWord32 :: (Word32, Word32, Word32, Word32) -> Word32+assembleWord32 (b0, b1, b2, b3) =+ shift b0 24 .|. shift b1 16 .|. shift b2 8 .|. b3++-------------------------------------------------------------------------------+
@@ -0,0 +1,86 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,+ FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Library.LittleEndian+ Description : Support for parsing of little endian data+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Library.LittleEndian where++import Language.Pads.Padsc+import Language.Pads.Library.BinaryUtilities++import qualified Data.Int+import qualified Data.Word+import Data.ByteString as B++-------------------------------------------------------------------------------+-- * Signed Integers+-- | type Int8 : signed byte low, 8-bit, signed integers+type Int8 = Data.Int.Int8+[pads| obtain Int8 from Bytes 1 using <|(bToi8,i8Tob)|> |]+bToi8 :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)+bToi8 p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)+i8Tob (i,md) = (B.singleton (fromIntegral i), md)++int8_genM :: PadsGen st Int8+int8_genM = randNum+++-- | type Int16 : signed byte low, 16-bit, signed integers+type Int16 = Data.Int.Int16+[pads| obtain Int16 from Bytes 2 using <| (bToi16sbl,i16sblTob) |> |]+bToi16sbl p (bs,md) = (bytesToInt16 SBL bs, md)+i16sblTob (i,md) = (int16ToBytes SBL i, md)++int16_genM :: PadsGen st Int16+int16_genM = randNum+++-- | type Int32 : signed byte low, 32-bit, signed integers+type Int32 = Data.Int.Int32+[pads| obtain Int32 from Bytes 4 using <| (bToi32sbl,i32sblTob) |> |]+bToi32sbl p (bs,md) = (bytesToInt32 SBL bs, md)+i32sblTob (i,md) = (int32ToBytes SBL i, md)++int32_genM :: PadsGen st Int32+int32_genM = randNum+++-------------------------------------------------------------------------------+-- * Unsigned Integers (aka Words)+-- | type Word8 : signed byte low, 8-bit, unsigned integers+type Word8 = Data.Word.Word8+[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]+bTow8 p (bytes,md) = (bytes `B.index` 0, md)+w8Tob (i,md) = (B.singleton i, md)++word8_genM :: PadsGen st Word8+word8_genM = randNum+++type Word16 = Data.Word.Word16+-- | type Word16 : signed byte low, 16-bit, unsigned integers+[pads| obtain Word16 from Bytes 2 using <| (bTow16sbl,w16sblTob) |> |]+bTow16sbl p (bs,md) = (bytesToWord16 SBL bs, md)+w16sblTob (i,md) = (word16ToBytes SBL i, md)++word16_genM :: PadsGen st Word16+word16_genM = randNum+++type Word32 = Data.Word.Word32+-- | type Word32 : signed byte low, 32-bit, unsigned integers+[pads| obtain Word32 from Bytes 4 using <| (bTow32sbl,w32sblTob) |> |]+bTow32sbl p (bs,md) = (bytesToWord32 SBL bs, md)+w32sblTob (i,md) = (word32ToBytes SBL i, md)++word32_genM :: PadsGen st Word32+word32_genM = randNum
@@ -0,0 +1,78 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, DeriveDataTypeable, ScopedTypeVariables, MultiParamTypeClasses,+ FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Library.Native+ Description : Support for parsing of native byte order data+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Library.Native where++import Language.Pads.Padsc+import Language.Pads.Library.BinaryUtilities++import qualified Data.Int+import qualified Data.Word+import Data.ByteString as B++-------------------------------------------------------------------------------+-- * Signed Integers+-- | type Int8 : 8-bit, signed integers+type Int8 = Data.Int.Int8+[pads| obtain Int8 from Bytes 1 using <|(bToi8,i8Tob)|> |]+bToi8 :: Span -> (Bytes, Base_md) -> (Data.Int.Int8, Base_md)+bToi8 p (bytes,md) = (fromIntegral (bytes `B.index` 0), md)+i8Tob :: (Int8,Int8_md) -> (Bytes,Bytes_md)+i8Tob (i,md) = (B.singleton (fromIntegral i), md)+++-- | type Int16 : 16-bit, signed integers; bytes assembled in order+type Int16 = Data.Int.Int16+[pads| obtain Int16 from Bytes 2 using <| (bToi16,i16Tob) |> |]+bToi16 :: Span -> (Bytes,Bytes_md) -> (Int16,Int16_md)+bToi16 p (bs,md) = (bytesToInt16 Native bs, md)+i16Tob :: (Int16,Int16_md) -> (Bytes,Bytes_md)+i16Tob (i,md) = (int16ToBytes Native i, md)+++-- | type Int32 : 32-bit, signed integers; bytes assembled in order+type Int32 = Data.Int.Int32+[pads| obtain Int32 from Bytes 4 using <|(bToi32,i32Tob)|> |]+bToi32 :: Span -> (Bytes,Bytes_md) -> (Int32,Int32_md)+bToi32 p (bytes,md) = (bytesToInt32 Native bytes, md)+i32Tob :: (Int32,Int32_md) -> (Bytes,Bytes_md)+i32Tob (i,md) = (int32ToBytes Native i, md)++-------------------------------------------------------------------------------+-- * Unsigned Integers (aka Words)+-- | type Word8 : 8-bit, unsigned integers, raw order+type Word8 = Data.Word.Word8+[pads| obtain Word8 from Bytes 1 using <|(bTow8,w8Tob)|> |]+bTow8 :: Span -> (Bytes,Bytes_md) -> (Word8,Word8_md)+bTow8 p (bytes,md) = (bytes `B.index` 0, md)+w8Tob :: (Word8,Word8_md) -> (Bytes,Bytes_md)+w8Tob (i,md) = (B.singleton i, md)++-- | type Word16 : 16-bit, unsigned integers, raw order+type Word16 = Data.Word.Word16+[pads| obtain Word16 from Bytes 2 using <|(bTow16,w16Tob)|> |]+bTow16 :: Span -> (Bytes,Bytes_md) -> (Word16,Word16_md)+bTow16 p (bytes,md) = (bytesToWord16 Native bytes, md)+w16Tob :: (Word16,Word16_md) -> (Bytes,Bytes_md)+w16Tob (i,md) = (word16ToBytes Native i, md)++-- | type Word32 : 32-bit, unsigned integers, raw order+type Word32 = Data.Word.Word32+[pads| obtain Word32 from Bytes 4 using <|(bTow32,w32Tob)|> |]+bTow32 :: Span -> (Bytes,Bytes_md) -> (Data.Word.Word32,Word32_md)+bTow32 p (bytes,md) = (bytesToWord32 Native bytes, md)+w32Tob :: (Data.Word.Word32,Word32_md) -> (Bytes,Bytes_md)+w32Tob (i,md) = (word32ToBytes Native i, md)++
@@ -0,0 +1,136 @@+{-# LANGUAGE Rank2Types, TypeFamilies, KindSignatures, NamedFieldPuns, DisambiguateRecordFields+ , FlexibleInstances, DeriveDataTypeable, ConstraintKinds, MultiParamTypeClasses+ , ScopedTypeVariables, FlexibleContexts #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.MetaData+ Description : Metadata produced by a Pads parser+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ ++-}+module Language.Pads.MetaData where++import qualified Language.Pads.Errors as E+import qualified Language.Pads.Source as S+import Text.PrettyPrint.Mainland as PP+import Text.PrettyPrint.Mainland.Class++import System.Posix.Types++import Data.Generics+import Data.Map (Map(..))+import qualified Data.Map as Map+import Data.Set (Set(..))+import qualified Data.Set as Set+import Data.List++-- | Base type library support for internal (to Pads) metadata+data Base_md = Base_md { numErrors :: Int+ , errInfo :: Maybe E.ErrInfo+ -- Need to add location information, etc.+ }+ deriving (Typeable, Data, Eq, Ord, Show)+++-- | Meta data type class+class Data md => PadsMD md where+ get_md_header :: md -> Base_md+ replace_md_header :: md -> Base_md -> md++-- | The trivial case for when the Pads parser doesn't need to add any metadata.+instance PadsMD Base_md where+ get_md_header b = b+ replace_md_header old new = new++-- | If we have a 2-tuple where the first thing is of type Base_md, then the tuple+-- itself is a Pads metadata instance.+instance Data b => PadsMD (Base_md,b) where+ get_md_header (h,b) = h+ replace_md_header (h1,b) h2 = (h2,b)++-- | Default metadata instance with no errors being reported.+cleanBasePD = Base_md {numErrors = 0, errInfo = Nothing }++-- | Default metadata instance with a generic "file error" being reported.+errorBasePD msg path = Base_md {numErrors = 1, errInfo = Just (E.ErrInfo (E.FileError msg path) Nothing) }++-- | Metadata merge+mergeBaseMDs :: [Base_md] -> Base_md+mergeBaseMDs mds = foldl addInfo cleanBasePD mds+ where+ addInfo (Base_md {numErrors=num1,errInfo=i1})+ (Base_md {numErrors=num2,errInfo=i2})+ = Base_md {numErrors=num1 + num2, errInfo= E.maybeMergeErrInfo i1 i2 }++-- | Metadata for a single parse error occuring at some location 'Loc'.+mkErrBasePDfromLoc msg loc+ = Base_md {numErrors = 1,+ errInfo = Just (E.ErrInfo{msg=msg,position= Just (S.locToSpan loc)}) }++-- | Metadata for a single parse error occuring at some position 'Span'.+mkErrBasePD msg pos+ = Base_md {numErrors = 1,+ errInfo = Just (E.ErrInfo{msg=msg,position= pos}) }++instance Pretty Base_md where+ ppr = pprBaseMD++-- | Pretty printer for the base metadata type.+pprBaseMD Base_md {numErrors=num, errInfo = info}+ = text "Errors:" <+> ppr num <+>+ case info of+ Nothing -> PP.empty+ Just e -> ppr e++type family Meta (rep :: *) :: *++-- | Fancy 'Generic' magic for defining a function that produces a default value+-- for any type so long as that type is an instance of Data. We do this by+-- selecting the first alternative of algebraic data types and recursively+-- filling in any nested types with default values as well. For instance:+--+-- > > :set -XDeriveDataTypeable+-- > > type Bar = (Int,Char)+-- > > data Foo = A Bar Bar | B | C deriving (Data, Show)+-- > > myempty :: Foo+-- > A (0,'\NUL') (0,'\NUL')+myempty :: forall a. Data a => a+myempty = general+ `extB` char+ `extB` int+ `extB` integer+ `extB` float+ `extB` double+ `extB` coff+ `extB` epochTime+ `extB` fileMode+ `ext2B` map+ `ext1B` set+ `ext1B` list where+ -- Generic case+ general :: Data a => a+ general = fromConstrB myempty (indexConstr (dataTypeOf general) 1)++ -- Base cases+ char = '\NUL'+ int = 0 :: Int+ integer = 0 :: Integer+ float = 0.0 :: Float+ double = 0.0 :: Double+ coff = 0 :: COff+ epochTime = 0 :: EpochTime+ fileMode = 0 :: FileMode+ list :: Data b => [b]+ list = []+ map :: (Data k,Data v) => Map k v+ map = Map.empty+ set :: Data k => Set k+ set = Set.empty+
@@ -0,0 +1,534 @@+{-# LANGUAGE NamedFieldPuns #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.PadsParser+ Description : The parsing monad for Pads+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ These are the combinators used to build PADS parsers. In this module we define+ the 'PadsParser' parsing monad which operates in a model where each parsing+ step (bind in the monad) runs a function `f :: Source -> (a, Source)`. This is+ similar to how the 'Read' typeclass implements parsing where we return the thing+ parsed by `f` of type `a` along with the remainder source input of type+ `Source`.++ Some important notes for future developers:+ - 'primPads' and 'queryP' below let you define new PadsParsers using Haskell+ functions without having to crack open the monad yourself.+ - As soon as the monad encounters a failure, we stop parsing and return the+ parsed result as far as we got in the input string.++-}++module Language.Pads.PadsParser where++import qualified Language.Pads.Source as S+import Language.Pads.Errors+import Language.Pads.MetaData+import Language.Pads.RegExp+import Data.Char+import Data.Word++import Control.Applicative (Applicative(..))+import Control.Monad++-- | Take a 'PadsParser' for some type and an input 'String' and parse the+-- 'String' using the 'PadsParser'.+parseStringInput :: PadsParser a -> String -> (a,String)+parseStringInput pp cs =+ let ((r,rest),b) = pp # S.padsSourceFromString cs+ in (r, S.padsSourceToString rest)++-- | Same as 'parseStringInput' but with a 'RawStream' source as input.+parseByteStringInput :: PadsParser a -> S.RawStream -> (a, S.RawStream)+parseByteStringInput pp cs =+ let ((r,rest),b) = pp # S.padsSourceFromByteString cs+ in (r, S.padsSourceToByteString rest)++-- | Same as 'parseStringInput' but with a 'FilePath' as input and 'IO' output.+parseFileInput :: PadsParser a -> FilePath -> IO a+parseFileInput pp file = do+ source <- S.padsSourceFromFile file+ let ((r,rest),b) = pp # source+ return r++-- | Same as 'parseFileInput' but with the ability to specify a non-default+-- record discipline.+parseFileInputWithDisc :: S.RecordDiscipline -> PadsParser a -> FilePath -> IO a+parseFileInputWithDisc d pp file = do+ source <- S.padsSourceFromFileWithDisc d file+ let ((r,rest),b) = pp # source+ return r++-------------------------------------------------------------------------------+-- * The Pads Parsing Monad++-- | A Pads parser is a function over inputs to some type `a` and the remaining+-- input.+newtype PadsParser a = PadsParser { (#) :: S.Source -> Result (a,S.Source) }++-- | A Pads parse result is just a tuple of the type parsed and a boolean+-- indicating whether or not a parse error occured. If the boolean is False,+-- the result type has been populated with default values. See+-- "Language.Pads.Generic" for the type class implementing default values, and+-- "Language.Pads.CoreBaseTypes" for definitions of default values for the+-- built-in types.+type Result a = (a,Bool)++-- | A Pads parser can be mapped over, which just says we need to run the+-- parser, grab the resulting parsed value, and apply the function we're mapping+-- to that result.+instance Functor PadsParser where+ fmap f p = PadsParser $ \bs -> let ((x,bs'),b) = p # bs in+ ((f x, bs'),b)++-- | This monad instance for Pads parsers looks just like any other sequencing+-- monad (run the first one and pipe the result into the second) with one thing+-- added: if any results on the way are bad, then the whole parse is bad.+instance Monad PadsParser where+ return r = PadsParser $ \bs -> ((r,bs), True)+ p >>= f = PadsParser $ \bs -> let ((v,bs'),b) = p # bs+ ((w,bs''),b') = f v # bs'+ in ((w,bs''), b && b')++-- | Applicative instance for 'PadsParser' to satisfy GHC+instance Applicative PadsParser where+ pure = return+ (<*>) = ap++-- | A pads parsing combinator used by other pads parsers when they detect a+-- parse error.+badReturn r = PadsParser $ \bs -> ((r,bs), False)++-- | +mdReturn (rep,md) = PadsParser $+ \bs -> (((rep,md),bs), numErrors (get_md_header md) == 0)++-- | Construct a Pads parser which always returns the given value and metadata+-- reporting no errors.+returnClean :: t -> PadsParser (t, Base_md)+returnClean x = return (x, cleanBasePD)++-- | Construct a Pads parser which always reports the given error message along+-- with returning a (likely default) value given to us.+returnError :: t -> ErrMsg -> PadsParser (t, Base_md)+returnError x err = do loc <- getLoc+ badReturn (x, mkErrBasePDfromLoc err loc)++infixl 5 =@=, =@++-- | +(=@=) :: PadsParser (t3 -> t2, t1 -> t)+ -> PadsParser (t3, t1)+ -> PadsParser (t2, t)+p =@= q = do + (f,g) <- p+ (rep,md) <- q+ return (f rep, g md)++(=@) :: PadsParser (t3, t2 -> t1)+ -> PadsParser (t, t2)+ -> PadsParser (t3, t1)+p =@ q = do+ (f,g) <- p+ (rep,md) <- q+ return (f, g md)++-------------------------------------------------------------------------------+-- * Source manipulation functions++-- | Run a pure function on the current source input from inside the+-- 'PadsParser' monad. Used for detecting things like 'isEOF', 'isEOR', or for+-- peaking at the current head of the input with 'peekHeadP'.+queryP :: (S.Source -> a) -> PadsParser a+queryP f = PadsParser $ \bs -> ((f bs,bs), True)++-- | Run a pure function to mutate the current input source.+primPads :: (S.Source -> (a,S.Source)) -> PadsParser a+primPads f = PadsParser $ \bs -> (f bs, True)++-- | Lift a function which runs in the 'Maybe' monad to run in the 'PadsParser'+-- monad with the same semantics as 'primPads', with the added ability that a+-- Nothing produces a parse failure.+liftStoP :: (S.Source -> Maybe (a,S.Source)) -> a -> PadsParser a+liftStoP f def = PadsParser $ \bs ->+ case f bs of+ Nothing -> ((def,bs), False)+ Just (v,bs') -> ((v,bs'), True)++-- | Replace the source in the given 'Result' with the given 'Source'+replaceSource :: S.Source -> Result (a,S.Source) -> Result (a,S.Source)+replaceSource bs ((v,_),b) = ((v,bs),b)++-------------------------------------------------------------------------------+-- * Monad choice combinators++-- The monad is non-backtracking. The only choice point is at ChoiceP++-- | One-by-one try a list of parsers in order until you find the one that works+-- and return that one. If none of them work, return the last one that failed.+choiceP :: [PadsParser a] -> PadsParser a+choiceP ps = foldr1 (<||>) ps++-- | Try the first parser and if it fails, try the second parser+(<||>) :: PadsParser a -> PadsParser a -> PadsParser a+p <||> q = PadsParser $ \bs -> (p # bs) <++> (q # bs)++-- | Grab the first result if it succeeded, otherwise use the second one+(<++>) :: Result a -> Result a -> Result a+(r, True) <++> _ = (r, True)+(r1, False) <++> r2 = r2 -- A number of functions rely on this being r2++-------------------------------------------------------------------------------++-- | Run the given Pads parser on the current input, but after running it+-- replace the (now possibly mutated input) with the original input while+-- returning the result parsed.+parseTry :: PadsMD md => PadsParser (rep,md) -> PadsParser (rep,md)+parseTry p = do+ (rep, md) <- PadsParser $ \bs -> replaceSource bs (p # bs)+ mdReturn (rep, md)++-------------------------------------------------------------------------------+-- * Parsers for Pads language features++-- | This is where constraint predicates get run and converted into error+-- messages upon predicate failure.+parseConstraint :: PadsMD md =>+ PadsParser(rep,md) -> (rep -> md -> Bool) -> PadsParser(rep, md)+parseConstraint p pred = do+ (rep,md) <- p+ mdReturn (rep, replace_md_header md (constraintReport (pred rep md) md))++-- | Convert the result of running a Pads constraint predicate into an error+-- message.+constraintReport :: PadsMD md => Bool -> md -> Base_md+constraintReport isGood md = Base_md {numErrors = totErrors, errInfo = errors}+ where+ Base_md {numErrors, errInfo} = get_md_header md+ totErrors = if isGood then numErrors else numErrors + 1+ errors = if totErrors == 0 then Nothing else+ Just(ErrInfo {msg = if isGood then UnderlyingTypedefFail+ else PredicateFailure,+ position = join $ fmap position errInfo})++-------------------------------------------------------------------------------++-- | Run the given parser and transform the result using the given Haskell+-- function, which originally looked like this in Pads syntax:+--+-- > type Foo = transform Bar => Baz using <|(bar2baz, baz2bar)|>+--+-- The first function in the antiquoted tuple (bar2baz) is run here, whereas the+-- second function in the tuple (baz2bar) is used during pretty printing.+parseTransform :: PadsMD dmd =>+ PadsParser (sr,smd) -> (S.Span->(sr,smd)->(dr,dmd)) -> PadsParser (dr,dmd)+parseTransform sParser transform = do+ begin_loc <- getLoc+ src_result <- sParser+ end_loc <- getLoc+ let src_pos = S.locsToSpan begin_loc end_loc+ return (transform src_pos src_result)++-------------------------------------------------------------------------------++-- | Run a parser with the appropriate record discipline enabled in the parsing+-- monad. See the 'RecordDiscipline' data type for the available disciplines+-- along with appropriate Haskell functions that can be referenced from a Pads+-- partition expression, e.g.:+--+-- > type Foo = partition Bar using none+--+-- Note that the record discipline specified in a partition expression remains+-- active until the parsing monad encounters another partition expression. This+-- effectively means that record disciplines form a stack that get popped off as+-- parsers complete. This stack however is implemented as scoped variables in+-- nested calls of this function rather than as a Haskell stack stored in the+-- monad.+parsePartition :: PadsMD md =>+ PadsParser(rep,md) -> S.RecordDiscipline -> PadsParser(rep, md)+parsePartition p newDisc = do+ oldDisc <- queryP S.getRecordDiscipline+ primPads (S.setRecordDiscipline newDisc)+ x <- p+ primPads (S.setRecordDiscipline oldDisc)+ return x++-------------------------------------------------------------------------------++-- | +parseListNoSepNoTerm :: PadsMD md =>+ PadsParser (rep,md) -> PadsParser ([rep], (Base_md, [md]))+parseListNoSepNoTerm p = listReport (parseMany p)++-- | +parseListSepNoTerm :: (PadsMD md, PadsMD mdSep) =>+ PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))+parseListSepNoTerm sep p = listReport (parseManySep sep p)++-- | +parseListNoSepLength :: (PadsMD md) =>+ Int -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))+parseListNoSepLength i p = listReport (parseCount i p)++-- | +parseListSepLength :: (PadsMD md, PadsMD mdSep) =>+ PadsParser (repSep,mdSep) -> Int -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))+parseListSepLength sep n p = listReport (parseCountSep n sep p)++-- | +parseListNoSepTerm :: (PadsMD md, PadsMD mdTerm) =>+ PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))+parseListNoSepTerm term p = listReport (parseManyTerm term p)++-- | +parseListSepTerm :: (PadsMD md, PadsMD mdSep, PadsMD mdTerm) =>+ PadsParser (repSep,mdSep) -> PadsParser (repTerm,mdTerm) ->+ PadsParser(rep, md) -> PadsParser ([rep], (Base_md, [md]))+parseListSepTerm sep term p = listReport (parseManySepTerm sep term p)++-- | +listReport :: PadsMD b => PadsParser [(a, b)] -> PadsParser ([a], (Base_md, [b]))+listReport p = do+ listElems <- p+ let (reps, mds) = unzip listElems+ let hmds = map get_md_header mds+ return (reps, (mergeBaseMDs hmds, mds))++-------------------------------------------------------------------------------++-- | Parse zero or more instances of the given parser. Stop parsing when the+-- parser encounters something it is unable to parse properly. This means,+-- during a valid parse, we attempt to parse more of the input than we really+-- should and only given up when there isn't a single valid parse.+parseMany :: PadsMD md => PadsParser (rep,md) -> PadsParser [(rep,md)]+parseMany p = do (r,m) <- p+ if (numErrors (get_md_header m) == 0)+ then do { rms <- parseMany p+ ; return ((r,m) : rms)}+ else badReturn []++ <||> return []++-- | Parse one or more instances of the given parser.+parseManySep :: (PadsMD md, PadsMD mdSep) => PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseManySep sep p = do { rm <- p+ ; rms <- parseManySep1 sep p+ ; return (rm : rms)+ }++-- | Parse zero or more instances of the given parser. TODO: The name of this+-- and 'parseManySep' are misleading / should be swapped?+parseManySep1 :: (PadsMD md, PadsMD mdSep) => PadsParser (repSep,mdSep) -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseManySep1 sep p = do (r,m) <- sep+ if (numErrors (get_md_header m) == 0)+ then parseManySep sep p+ else badReturn []+ <||> return []++-------------------------------------------------------------------------------++-- | Parse n instances of the given parser.+parseCount :: (PadsMD md) => Int -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseCount n p = sequence (replicate n p)++-- | Parse n instances of the given parser with another parser acting as the+-- separator between instances of the first parser. Note that this properly+-- intersperses the separator +parseCountSep :: (PadsMD md) =>+ Int -> PadsParser rmdSep -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseCountSep n sep p | n <= 0 = return []+parseCountSep n sep p = do+ rm <- p+ rms <- sequence $ replicate (n-1) (sep >> p)+ return (rm:rms)++-------------------------------------------------------------------------------++-- | Parse many instances of the given parser until we see an instance of the+-- terminator parser. Parsing satisfies the following rules in decreasing order+-- of precedence:+-- * If we see the terminator, parse it and stop parsing (even if the terminator+-- is ambiguous with the given parser).+-- * If we see the end of file, stop parsing and return what we've parsed thus+-- far.+-- * Parse an instance of the given parser and recurse.+parseManyTerm :: (PadsMD md, PadsMD mdTerm) =>+ PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseManyTerm term p = (term >> return [])+ <||> (ifEOFP >> return [])+ <||> do { rm <- p+ ; rms <- parseManyTerm term p+ ; return (rm:rms) }++-- | Like 'parseManyTerm' but with a separator in-between instances of the given+-- parser.+parseManySepTerm :: (PadsMD md, PadsMD mdSep, PadsMD mdTerm) =>+ PadsParser (repSep,mdSep) -> PadsParser (repTerm,mdTerm) -> PadsParser(rep, md) -> PadsParser [(rep,md)]+parseManySepTerm sep term p = (term >> return [])+ <||> (ifEOFP >> return [])+ <||> scan+ where+ scan = do (rep, md) <- p+ (terminated,junk) <- seekSep sep term+ case junk of+ [] -> if terminated then return [(rep,md)] else+ do rms <- scan+ return ((rep,md):rms)+ _ -> do sepLoc <- getLoc+ let report = junkReport md sepLoc junk+ if terminated then+ badReturn [(rep,report)]+ else do+ rms <- scan+ badReturn ((rep,report) : rms)++-- | Consume input until we find the terminator, separator, end-of-file, or+-- end-of-record. If we find (in decreasing order of precedence):+-- * The terminator, then report that we successfully terminated+-- * The end-of-file, report successful termination.+-- * The separator, report that we successfully seeked until a separator was+-- consumed from the input.+-- * An end-of-record symbol, report a bad parse+--+-- Note that the fact that we report successful termination upon end-of-file is+-- probably a bug, because it means we report a successful parse even though we+-- didn't find the terminator to the list being parsed.+seekSep sep term = (term >> return (True, []))+ <||> (ifEOFP >> return (True, []))+ <||> (sep >> return (False, []))+ <||> do { b <- isEORP+ ; if b then badReturn (False, []) else+ do { c <- takeHeadP+ ; (b,cs) <- seekSep sep term+ ; badReturn (b, c:cs)+ }+ }++-- | +junkReport md loc junk = replace_md_header md mergeMD+ where+ mdSep = mkErrBasePDfromLoc (ExtraStuffBeforeTy junk "separator" ) loc+ mergeMD = mergeBaseMDs [get_md_header md, mdSep]++-------------------------------------------------------------------------------++-- | Get the current source location offset into the data we're currently+-- parsing.+getLoc :: PadsParser S.Loc+getLoc = queryP S.getSrcLoc++isEOFP, isEORP :: PadsParser Bool+isEOFP = queryP S.isEOF+isEORP = queryP S.isEOR++ifEOFP, ifEORP :: PadsParser ()+ifEOFP = do { b <- isEOFP; if b then return () else badReturn ()}+ifEORP = do { b <- isEORP; if b then return () else badReturn ()}++-- | Remove and return the first n characters from the input source+takeP :: Integral a => a -> PadsParser String+takeP n = primPads (S.take (fromInt n))++-- | Remove and return the first n bytes from the input source+takeBytesP :: Integral a => a -> PadsParser S.RawStream+takeBytesP n = primPads (S.takeBytes (fromInt n))++takeBytesNBP :: Integral a => a -> PadsParser S.RawStream+takeBytesNBP n = primPads (S.takeBytesNB (fromInt n))++takeBitsP :: Integral a => a -> PadsParser Integer+takeBitsP b = primPads (S.takeBits (fromInt b))++takeBits8P :: Integral a => a -> PadsParser Word8+takeBits8P b = primPads (S.takeBits8 (fromInt b))++takeBits16P :: Integral a => a -> PadsParser Word16+takeBits16P b = primPads (S.takeBits16 (fromInt b))++takeBits32P :: Integral a => a -> PadsParser Word32+takeBits32P b = primPads (S.takeBits32 (fromInt b))++takeBits64P :: Integral a => a -> PadsParser Word64+takeBits64P b = primPads (S.takeBits64 (fromInt b))++fromInt :: (Integral a1, Num a) => a1 -> a+fromInt n = fromInteger $ toInteger n++-------------------------------------------------------------------------------++-- | Query the current symbol (character) of input+peekHeadP :: PadsParser Char+peekHeadP = queryP S.head++-- | Remove and return the current symbol (character) of input+takeHeadP :: PadsParser Char+takeHeadP = primPads S.takeHead++-- | See 'takeHeadStr' - returns false in the PadsParser monad iff the front of+-- current source matches the given string with the side effect of removing that+-- string from the front of the source if it does.+takeHeadStrP :: String -> PadsParser Bool+takeHeadStrP str = primPads (S.takeHeadStr str)++-- Return string is junk before found string+scanStrP :: String -> PadsParser (Maybe String)+scanStrP str = primPads (S.scanStr str)+++regexMatchP ::RE -> PadsParser (Maybe String)+regexMatchP re = primPads (S.regexMatch re)++regexStopP :: RE -> PadsParser (Maybe String)+regexStopP re = primPads (S.regexStop re)++scanP :: Char -> PadsParser Bool+scanP c = primPads (\s -> let (f,r,e) = S.scanTo c s in (f,r))++getAllP :: PadsParser String+getAllP = primPads S.drainSource++getAllBinP :: PadsParser S.RawStream+getAllBinP = primPads S.rawSource++drainSourceNBP :: PadsParser String+drainSourceNBP = primPads S.drainSourceNB++satisfy p = primPads loop+ where loop s = if S.isEOF s || S.isEOR s then ([],s) else+ let c = S.head s in+ if p c then+ let (xs,s') = loop (S.tail s) in+ (c:xs, s')+ else+ ([],s)++satisfyNBP :: (Char -> Bool) -> (PadsParser String)+satisfyNBP p = primPads (S.satisfyNB p)++digitListToInt :: Bool -> [Char] -> Int+digitListToInt isNeg digits = if isNeg then negate raw else raw+ where+ raw = foldl (\a d ->10*a + digitToInt d) 0 digits++-------------------------------------------------------------------------------++doLineBegin :: PadsParser ((), Base_md)+doLineBegin = do+ rbegErr <- primPads S.srcLineBegin+ case rbegErr of+ Nothing -> returnClean ()+ Just err -> returnError () (LineError err)+++doLineEnd :: PadsParser ((), Base_md)+doLineEnd = do+ rendErr <- primPads S.srcLineEnd+ case rendErr of+ Nothing -> returnClean ()+ Just err -> returnError () (LineError err)
@@ -0,0 +1,122 @@+{-# LANGUAGE FlexibleContexts, DeriveDataTypeable #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.PadsPrinter+ Description : Lazy Pads printing monad+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ This module provides a way to lazily append to a ByteString for the purpose+ of printing said ByteString.++-}+module Language.Pads.PadsPrinter where++import qualified Data.ByteString as B+import qualified Language.Pads.Source as S+import qualified Data.List as List+import Language.Pads.Errors+import Data.Typeable+import Language.Pads.MetaData+import Data.Data++{- Printing Monad -}++-- |+type PadsPrinter a = a -> FList++-- Lazy append-lists++-- |+type FList = B.ByteString -> B.ByteString++-- |+(+++) :: FList -> FList -> FList+p +++ q = p . q++-- |+nil :: FList+nil = id++-- |+concatFL :: [FList] -> FList+concatFL fs = foldr (+++) nil fs++-- |+printNothing :: FList+printNothing ws = ws++-- |+addBString :: B.ByteString -> FList+addBString bs = B.append bs++-- |+addString :: String -> FList+addString s = B.append (S.strToByteString s)++-- |+fshow :: Show a => a -> FList+fshow x = B.append (S.strToByteString (show x))++-- |+printEOR :: FList+printEOR = addString ['\n']++-- |+printEOF :: FList+printEOF = addString []++-- |+endRecord :: FList -> FList+endRecord fst = fst +++ printEOR++-- |+printF :: FList -> IO ()+printF q = Prelude.print (B.unpack (q B.empty))++--------------------------------------------------++printList' (reps, (_,mds)) printItem printSep printTerm = (concatFL (List.intersperse printSep (map printItem (zip reps $ mds ++ repeat myempty))) ) +++ printTerm++printList :: (Data r,Data m) => (PadsPrinter (r,m)) -> FList -> FList -> ([r], (Base_md,[m])) -> FList+printList printItem printSep printTerm (reps, (_,mds)) =+ (concatFL (List.intersperse printSep (map printItem (zip reps $ mds ++ repeat myempty))) )+ +++ printTerm++{-++++type IntPair = (Int,"|",Int)++=====>++type IntPair = (Int, Int)+type IntPair_md = (Base_md, (Base_md, Base_md))++intPair_parseM+ = let+ f_rep x1 x3 = (x1, x3)+ f_md x1 x2 x3+ = (mergeBaseMDs+ [get_md_header x1, get_md_header x2, get_md_header x3],+ (x1, x3))+ in+ (((return (f_rep, f_md) =@= int_parseM) =@ strLit_parseM "|")+ =@=+ int_parseM)++intPair_parseS = parseStringInput intPair_parseM]++intPair_printFL (r,m)+ = case (r,m) of+ ((r1,r2),(_,(m1,m2)))+ -> int_PrintFL (r1,m1) ++++ addString "|" ++++ int_PrintFL (r2,m2)++-}
@@ -0,0 +1,62 @@+{-# LANGUAGE TypeSynonymInstances, GeneralizedNewtypeDeriving, QuasiQuotes, TemplateHaskell, DeriveDataTypeable,+ ScopedTypeVariables, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,+ UndecidableInstances, NamedFieldPuns, RecordWildCards, StandaloneDeriving #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Padsc+ Description : Pads compiler+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ This module re-exports all the modules necessary to make use of the Pads+ quasiquoter and compilation infrastructure.++-}+module Language.Pads.Padsc (+ {- FIX: Languages.Pads.Source exports "take", which clashes with+ the function of the same name in Prelude -}+ module Language.Pads.Source,+ module Language.Pads.RegExp,+ module Language.Pads.Errors,+ module Language.Pads.PadsParser,+ module Language.Pads.MetaData,+ module Language.Pads.Generic,+ module Language.Pads.CoreBaseTypes,+ module Language.Pads.Quote,+ module Language.Pads.Syntax,+ module Language.Pads.BaseTypes,+ module Language.Pads.Pretty,+ module Language.Pads.PadsPrinter,+ module Language.Pads.Generation,+ module Data.Data,+ module Data.List,+ ppr, pretty+ )+ where++import Language.Pads.Source hiding (take, span, head, tail)+import Language.Pads.RegExp+import Language.Pads.Errors hiding (msg)+import Language.Pads.PadsParser+import Language.Pads.MetaData+import Language.Pads.Generic+import Language.Pads.CoreBaseTypes+import Language.Pads.Quote+import Language.Pads.Syntax+import Language.Pads.BaseTypes+import Language.Pads.Pretty+import Language.Pads.PadsPrinter+import Language.Pads.Generation++import Data.Data+import Data.List+import Text.PrettyPrint.Mainland hiding (line, dot)+import Text.PrettyPrint.Mainland.Class++{- Fix these should be reexported -}+-- parseAllS = Language.Pads.PadsParser.parseAllS+numErrors = Language.Pads.MetaData.numErrors
@@ -0,0 +1,447 @@+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Parser+ Description : Parser for the syntax of Pads+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ This module implements the parser for the PADS syntax in Haskell using parser+ combinators.+-}+module Language.Pads.Parser where++import Language.Pads.Syntax+++import Text.Parsec hiding (upper,lower)+import qualified Text.Parsec.String as PS+import Text.Parsec.Error+import Text.Parsec.Prim as PP+import qualified Text.Parsec.Token as PT+import Text.Parsec.Language+import Text.ParserCombinators.Parsec.Language+import Text.ParserCombinators.Parsec.Pos+import Text.Parsec.Expr+import Control.Monad++import qualified Language.Haskell.Meta as LHM+import Language.Haskell.TH++import Data.Char+--import System.FilePath.Glob++++type Parser = PS.Parser+type Env = [String]++-- | The main entry point for the Pads QuasiQuoter+parsePadsDecls :: SourceName -> Line -> Column -> String -> Either ParseError [PadsDecl]+parsePadsDecls fileName line column input+ = PP.parse (do { setPosition (newPos fileName line column)+ ; whiteSpace+ ; x <- padsDecls+ ; whiteSpace+ ; eof <|> errorParse+ ; return x+ }) fileName input++errorParse = do+ { rest <- manyTill anyToken eof+ ; unexpected rest }++-------------------------------------------------------------------------------+-- * PADS DECLARATIONS++padsDecls :: Parser [PadsDecl]+padsDecls = option [] (many1 topDecl)++topDecl :: Parser PadsDecl+topDecl+ = typeDecl <|> dataDecl <|> newDecl <|> obtainDecl+ <?> "Pads declaration keyword"++typeDecl :: Parser PadsDecl+typeDecl+ = do { reserved "type"+ ; (id,env) <- declLHS; pat <- patLHS+ ; rhs <- ptype env+ ; genM <- optionMaybe gen+ ; return (PadsDeclType id env pat rhs genM)+ } <?> "Pads type declaration"++dataDecl :: Parser PadsDecl+dataDecl+ = do { reserved "data"+ ; (id,env) <- declLHS; pat <- patLHS+ ; rhs <- dataRHS env; drvs <- option [] derives+ ; return (PadsDeclData id env pat rhs drvs)+ } <?> "Pads data declaration"++newDecl :: Parser PadsDecl+newDecl+ = do { reserved "newtype"+ ; (id,env) <- declLHS; pat <- patLHS+ ; rhs <- newRHS env; drvs <- option [] derives+ ; return (PadsDeclNew id env pat rhs drvs)+ } <?> "Pads newtype declaration"++obtainDecl :: Parser PadsDecl+obtainDecl+ = do { reserved "obtain"+ ; (id,env) <- declLHS+ ; reservedOp "from"; rhs <- ptype env+ ; reserved "using"; exp <- expression+ ; genM <- optionMaybe gen+ ; return (PadsDeclObtain id env rhs exp genM)+ } <?> "Pads transform type"++declLHS+ = do { id <- upper; env <- try $ many lower+ ; return (id,env)+ }++patLHS+ = do { p <- try $ haskellParsePatTill "="+ ; return (Just p)+ }+ <|> (reservedOp "=" >> return Nothing)++derives+ = reserved "deriving" >>+ (do { q <- qualUpper; return [q] }+ <|> parens (commaSep1 qualUpper))++-------------------------------------------------------------------------------+-- * PADS TYPES++ptype :: Env -> Parser PadsTy+ptype env+ = constrain env+ <|> obtain env+ <|> partition env+ <|> listTy env+ <|> value env+ <|> btype env+ <?> "Pads Pads type expression"++constrain :: Env -> Parser PadsTy+constrain env+ = do { reserved "constrain"+ ; pat <- haskellParsePatTill "::"; ty <- ptype env+ ; exp <- predic+ ; return (PConstrain pat ty exp)+ } <?> "Pads constrain type"++predic = do { reservedOp "where"; expression }+gen = do { reservedOp "generator"; expression }++obtain :: Env -> Parser PadsTy+obtain env+ = do { reserved "obtain"; dst <- ptype env+ ; reservedOp "from"; src <- ptype env+ ; reserved "using"; exp <- expression+ ; genM <- optionMaybe gen+ ; return (PTransform src dst exp genM)+ } <?> "Pads transform type"++partition :: Env -> Parser PadsTy+partition env+ = do { reserved "partition"; ty <- ptype env+ ; reserved "using"; exp <- expression+ ; return (PPartition ty exp)+ } <?> "Pads partition type"++listTy :: Env -> Parser PadsTy+listTy env+ = do { (elm,sepM) <- brackets (listInside env)+ ; termM <- listEnd env+ ; return (PList elm sepM termM)+ } <?> "Pads list type"++listInside env+ = do { elm <- ptype env+ ; sepM <- optionMaybe (reservedOp "|" >> ptype env)+ ; return (elm,sepM)+ }++listEnd env+ = optionMaybe+ ( do {reservedOp "terminator"; t<-ptype env; return (LTerm t)}+ <|> do {reservedOp "length"; e<-expression; return (LLen e)})++value env+ = do { reserved "value"+ ; exp <- expression; reservedOp "::"+ ; ty <- ptype env+ ; return (PValue exp ty)+ }+++btype :: Env -> Parser PadsTy+btype env+ = try $ do+ { ty <- etype env; tys <- many (atype env)+ ; expM <- optionMaybe (try expression);+ ; if length tys==0 && expM == Nothing+ then return ty+ else return (PApp (ty:tys) expM) }++etype :: Env -> Parser PadsTy+etype env = atype env+ <|> try (expression >>= (return . PExpression))++atype env+ = try (tuple env)+ <|> do { (elm,sepM) <- brackets (listInside env)+ ; return (PList elm sepM Nothing)}+ <|> fmap PTycon qualUpper+ <|> fmap PTyvar (tyvar env)++tuple :: Env -> Parser PadsTy+tuple env+ = do { tys <- parens $ option [] (commaSep1 (ptype env))+ ; case length tys of+ 0 -> return (PTycon ["Void"])+ 1 -> return (head tys)+ _ -> return (PTuple tys)+ }+ <?> "Pads tuple type"++-------------------------------------------------------------------------------+-- * PADS DATA DECLARATIONS++dataRHS :: Env -> Parser PadsData+dataRHS env+ = switchTy env+ <|> fmap PUnion (constrs env)+ <?> "Pads data type right hand side"++switchTy :: Env -> Parser PadsData+switchTy env+ = do { reservedOp "case"; exp <- expression+ ; reservedOp "of"; brs <- branch env `sepBy1` reservedOp "|"+ ; return (PSwitch exp brs)+ } <?> "Pads switch type"++branch :: Env -> Parser (Pat, BranchInfo)+branch env+ = do { pat <- haskellParsePatTill "->"; br <- constr env+ ; return (pat, br)+ } <?> "Pads switch branch"++constrs :: Env -> Parser [BranchInfo]+constrs env = constr env `sepBy1` reservedOp "|"++constr :: Env -> Parser BranchInfo+constr env+ = do { id <- upper;+ ; do { args <- record env; predM <- optionMaybe predic+ ; return (BRecord id args predM)}+ <|> do { args <- option (mkId id) (constrArgs env)+ ; predM <- optionMaybe predic+ ; return (BConstr id args predM)}}+ where+ mkId id = [(NotStrict, PExpression (LitE (StringL id)))]+ -- Provides the expansion e.g.: Tue -> Tue "Tue"+++constrArgs :: Env -> Parser [ConstrArg]+constrArgs env+ = many1 $ do+ { bang <- option NotStrict (reservedOp "!" >> return IsStrict)+ ; ty <- etype env+ ; return (bang,ty)+ }+++record :: Env -> Parser [FieldInfo]+record env+ = do { reservedOp "{"+ ; flds <- field env `sepBy` reservedOp ","+ ; reservedOp "}"+ ; return flds+ } <?> "Pads record type"++field :: Env -> Parser FieldInfo+field env+ = try (do { id <- (lower << reservedOp "::")+ ; ty <- ftype env+ ; predM <- optionMaybe predic+ ; genM <- optionMaybe gen+ ; return (Just id, ty, predM, genM)+ })+ <|> try (do { id <- lower; reservedOp "="+ ; reserved "value"+ ; exp <- expression; reservedOp "::"+ ; (strict,ty) <- ftype env+ ; predM <- optionMaybe predic+ ; genM <- optionMaybe gen+ ; return (Just id, (strict, PValue exp ty), predM, genM)+ })+ <|> do { ty <- ftype env+ ; let recordid = (case ty of+ (strict,PConstrain (VarP name) _ _) -> Just $ nameBase name+ otherwise -> Nothing+ )+ ; predM <- optionMaybe predic+ ; genM <- optionMaybe gen+ ; return (recordid, ty, predM, genM)+ }+ <?> "record field"++ftype env+ = do { reservedOp "!"; ty <- atype env; return (IsStrict,ty)}+ <|> do { ty <- ptype env; return (NotStrict,ty)}++-------------------------------------------------------------------------------+-- * PADS NEW TYPE DECLARATIONS++newRHS :: Env -> Parser BranchInfo+newRHS env+ = do { id <- upper;+ ; do { rec <- record1 env+ ; predM <- optionMaybe predic+ ; return (BRecord id rec predM)}+ <|> do { arg <- atype env+ ; predM <- optionMaybe predic+ ; return (BConstr id [(NotStrict,arg)] predM)+ }+ }++record1 :: Env -> Parser [FieldInfo]+record1 env+ = do { reservedOp "{"+ ; args1 <- many (ftype env << reservedOp ",")+ ; fld <- field1 env+ ; args2 <- many (reservedOp "," >> ftype env)+ ; reservedOp "}"+ ; return (map expand args1 ++ [fld] ++ map expand args2)+ } <?> "Pads newtype record"+ where+ expand fty = (Nothing, fty, Nothing, Nothing)++field1 :: Env -> Parser FieldInfo+field1 env+ = do { id <- lower; reservedOp "::"; ty <- ptype env+ ; predM <- optionMaybe predic+ ; genM <- optionMaybe gen+ ; return (Just id, (NotStrict,ty), predM, genM)+ }++-------------------------------------------------------------------------------+-- * HASKELL IN PADS DECLARATIONS++expression :: Parser Exp+expression = haskellExp+ <|> literal++haskellExp :: Parser Exp+haskellExp = do { reservedOp "<|"+ ; haskellParseExpTill "|>"+ }+ <?> "Pads Haskell expression"+++haskellParseExp :: String -> Parser Exp+haskellParseExp str = case LHM.parseExp str of+ Left err -> parserZero+ Right expTH -> return expTH++haskellParseExpTill :: String -> Parser Exp+haskellParseExpTill op = do { str <- manyTill anyChar (reservedOp op)+ ; haskellParseExp str+ }++haskellParsePat :: String -> Parser Pat+haskellParsePat str = case LHM.parsePat str of+ Left err -> parserZero+ Right patTH -> return patTH++haskellParsePatTill :: String -> Parser Pat+haskellParsePatTill op = do { str <- manyTill anyChar (reservedOp op)+ ; haskellParsePat str+ }+++literal :: Parser Exp+literal = fmap (LitE . CharL) (try charLiteral)+ <|> reLiteral+ <|> fmap (LitE . StringL) stringLiteral+ <|> fmap (LitE . IntegerL) (try integer)+ <|> fmap (VarE . mkName . qName) qualLower+ <|> fmap (ConE . mkName . qName) qualUpper+ <?> "Pads literal"++reLiteral :: Parser Exp+reLiteral = do { reservedOp reMark+ ; str <- manyTill anyChar (reservedOp reMark)+ ; return (ConE (mkName "RE") `AppE` LitE (StringL str))+ }+reMark = "'"++literalPat :: Parser Pat+literalPat = fmap (LitP . CharL) (try charLiteral)+ <|> reLiteralPat+ <|> fmap (LitP . StringL) stringLiteral+ <|> fmap (LitP . IntegerL) (try integer)+ <|> fmap (VarP . mkName . qName) qualLower+ <|> fmap (flip ConP [] . mkName . qName) qualUpper+ <?> "Pads literal"++reLiteralPat :: Parser Pat+reLiteralPat = do { reservedOp reMark+ ; str <- manyTill anyChar (reservedOp reMark)+ ; return (ConP (mkName "RE") [LitP (StringL str)])+ }++qualUpper, qualLower :: Parser QString+qualUpper = try (upper `sepBy1` reservedOp ".")+qualLower = try $ do { prefix <- many (upper << reservedOp ".")+ ; final <- lower+ ; return (prefix ++ [final])+ }++upper :: Parser String+upper = try $ do { id <- identifier+ ; guard $ isUpper (head id)+ ; return id}++lower :: Parser String+lower = try $ do { id <- identifier+ ; guard $ isLower (head id)+ ; return id}++tyvar env = try $ do { v <- lower+ ; guard (v `elem` env)+ ; return v }++-------------------------------------------------------------------------------+-- * LEXER++p << q = do {x<-p;q;return x}+++lexer :: PT.TokenParser ()+lexer = PT.makeTokenParser (haskellStyle+ { reservedOpNames = ["=", "=>", "{", "}", "::", "<|", "|>", "|", reMark, "." ],+ reservedNames = ["data", "type", "newtype", "old", "existing", "deriving",+ "using", "where", "terminator", "length", "of", "from",+ "case", "constrain", "obtain", "partition","value","generator" ]})++whiteSpace = PT.whiteSpace lexer+identifier = PT.identifier lexer+operator = PT.operator lexer+reserved = PT.reserved lexer+reservedOp = PT.reservedOp lexer+charLiteral = PT.charLiteral lexer+stringLiteral = PT.stringLiteral lexer+integer = PT.integer lexer+commaSep1 = PT.commaSep1 lexer+parens = PT.parens lexer+braces = PT.braces lexer+brackets = PT.brackets lexer
@@ -0,0 +1,173 @@+{-# LANGUAGE NamedFieldPuns,RecordWildCards #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Pretty+ Description : Pretty printing utilities for Pads types+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Pretty where+import Data.Char (isPrint, ord)+import qualified Data.Map as M+import qualified Language.Haskell.TH as TH++import Text.PrettyPrint.Mainland as PP+import Text.PrettyPrint.Mainland.Class+import Language.Pads.Syntax+import qualified Language.Pads.Parser as P+import Language.Pads.RegExp+++instance Pretty PadsDecl where+ ppr (PadsDeclType con vars pat padsty _) = text "type" <+> (ppr_decl_lhs con vars pat) <+> text "=" <+> ppr padsty+ ppr (PadsDeclData con vars pat padsrhs cons) = text "data" <+> (ppr_decl_lhs con vars pat) <+> text "="+ <+> ppr padsrhs <> ppr_derives cons+ ppr (PadsDeclNew con vars pat branchInfo cons) = text "newtype" <+> (ppr_decl_lhs con vars pat) <+> text "="+ <+> ppr branchInfo <> ppr_derives cons++ppr_decl_lhs id args patOpt = text id <> ppr_args args <> ppr_optArgPat patOpt+ppr_derives cons = case cons of+ [] -> empty+ [l] -> space <> text (qName l)+ ls -> space <> tuple (map (text . qName) cons)++ppr_args args = case args of [] -> empty ; _ -> space <> (spread (map text args))+++instance Pretty PadsData where+ ppr (PUnion branches) = ppr_branches branches+ ppr (PSwitch exp patBranches) = text "case" <+> ppr exp <+> text "of" <+> ppr_patBranches patBranches++ppr_patBranches patBranches = enclosesep empty empty (text " |") (map ppr_patBranch patBranches)+ppr_patBranch (pat, branchInfo) = ppr pat <+> text "->" <+> ppr branchInfo+ppr_branches branches = enclosesep empty empty (text " |") (map ppr branches)++instance Pretty BranchInfo where+ ppr (BRecord con fields predOpt) = text con <+> braces (commasep (map ppr_fieldInfo fields)) <> (ppr_optPred predOpt)+ ppr (BConstr con constrArgs predOpt) = (ppr_conApp con constrArgs) <> (ppr_optPred predOpt)++ppr_conApp con constrArgs = case constrArgs of+ [(NotStrict,arg)] | argIsCon con arg -> text con+ otherwise -> text con <+> (spread (map ppr_constrArgApp constrArgs))+++argIsCon con arg = case arg of+ PExpression (TH.LitE (TH.StringL str)) -> con == str+ otherwise -> False++ppr_fieldInfo (varOpt, constrArg, expOpt, _)+ = (case varOpt of Nothing -> empty ; Just var -> (text var) <+> (text "::") <> space)+ <> ppr_constrArg constrArg+ <> ppr_optPred expOpt++ppr_constrArg (strict, padsTy) = ppr_strict strict <> ppr padsTy++ppr_constrArgApp (strict, padsTy)+ | isAtomicTy padsTy = ppr_strict strict <> ppr padsTy+ | otherwise = ppr_strict strict <> parens (ppr padsTy)++ppr_alpha padsTy+ | isAtomicTy padsTy = ppr padsTy+ | otherwise = parens (ppr padsTy)++ppr_strict IsStrict = text "!"+ppr_strict NotStrict = empty++isAtomicTy (PList _ _ _ ) = True+isAtomicTy (PTycon _ ) = True+isAtomicTy (PTyvar _ ) = True+isAtomicTy (PExpression _ ) = True+isAtomicTy (PTuple _ ) = True+isAtomicTy _ = False+++instance Pretty PadsTy where+ ppr (PConstrain pat ty exp) = text "constrain" <+> ppr pat <+> text "::" <+> ppr ty <+> text "where" <+> ppr exp+ ppr (PTransform sty dty exp _) = text "transform" <+> ppr sty <+> text "=>" <+> ppr dty <+> text "using" <+> ppr exp+ ppr (PList itemTy sepTy termTy) = ppr_padsList itemTy sepTy termTy+ ppr (PValue exp ty) = text "value" <+> ppr exp <+> text "::" <+> ppr ty+ ppr (PApp argTys expArgOpt) = spread (map ppr_alpha argTys) <> ppr_opt expArgOpt+ ppr (PTuple tys) = tuple (map ppr tys)+ ppr (PExpression exp) = ppr exp+ ppr (PTycon con) = text (qName con)+ ppr (PTyvar var) = text var++instance Pretty TH.Pat where+ ppr = text . TH.pprint++pprHpat pat = case pat of+ TH.TupP p -> ppr pat+ otherwise -> parens (ppr pat)++instance Pretty TH.Exp where+ ppr = pprHexp++pprHexp exp = case exp of+ TH.VarE name -> text(TH.pprint exp)+ TH.ConE name -> text(TH.pprint exp)+ TH.LitE lit -> text(TH.pprint exp)+ TH.AppE (TH.ConE re) (TH.LitE (TH.StringL str)) | re==TH.mkName "RE"+ -> text("'"++str++"'")+ otherwise -> ppr_bird (text(TH.pprint exp))++ppr_bird s = (text "<|") <> s <> (text "|>")++instance Pretty TermCond where+ ppr (LTerm ty) = text "terminator" <+> ppr ty+ ppr (LLen exp) = text "length" <+> ppr exp+++ppr_padsList itemTy sepTyOpt termTyOpt = brackets (ppr itemTy <> ppr_sep sepTyOpt) <> ppr_opt termTyOpt++ppr_opt opt = case opt of Nothing -> empty ; Just e -> (space <> ppr e)+ppr_optArgPat pat = case pat of Nothing -> empty; Just e -> (space <> pprHpat e)++ppr_optPred pred = case pred of Nothing -> empty; Just e -> (space <> text "where" <+> ppr e)++ppr_sep Nothing = empty+ppr_sep (Just sepTy) = text " |" <+> ppr sepTy+++++{- Utilities for generated pretty printer for PADS types -}+seplines :: Doc -> [Doc] -> Doc+seplines s = folddoc (\hd tl -> hd <> s </> tl)++whitesep = sep+field_ppr field_name ppr = text field_name <+> equals <+> ppr+record_ppr str pprs = namedty_ppr str (recordbody_ppr pprs)+recordbody_ppr docs = braces (align (seplines comma docs))++tuple_ppr ds = parens (align (commasep ds))++maybe_ppr d = case d of+ Nothing -> text "Nothing"+ Just a -> ppr a+++namedty_ppr str ph = hang 2 (text str <+/> ph)++namedtuple_ppr :: String -> [Doc] -> Doc+namedtuple_ppr name pprls = group $ hang 2 (text name <+/> (tuple_ppr pprls))+++list_ppr ds = (text "[---" <//>+ align (seplines comma ds ) <//>+ text "]")++--instance (Pretty a, Pretty b) => Pretty (M.Map a b) where+-- ppr = map_ppr+map_ppr d = list_ppr (map ppr (M.toList d))++string_ppr :: String -> Doc+string_ppr = ppr+++namedlist_ppr :: String -> [Doc] -> Doc+namedlist_ppr name pprls = group $ hang 2 (text name <+/> (list_ppr pprls))
@@ -0,0 +1,81 @@+{-|+ Module : Language.Pads.Quote+ Description : Quasiquoter+ Copyright : (c) 2005-2011 AT&T+ Kathleen Fisher <kfisher@research.att.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Quote+ (pads, padsDerivation, pparseDecl, make_pads_declarations, padsE)+ where++import Prelude hiding (exp, init)+import System.IO.Unsafe (unsafePerformIO)+import Control.Monad (liftM2, liftM)++import Language.Haskell.TH+import Language.Haskell.TH.Quote (QuasiQuoter(..))++import Language.Pads.Syntax (PadsDecl(..))+import Language.Pads.CodeGen+import qualified Language.Pads.Parser as P++-- | The PADS quasiquoter which can be invoked by e.g.:+--+-- > [pads| type MyType = (Int, Int) |]+pads :: QuasiQuoter+pads = padsDerivation (const $ return [])++-- | Same as /pads/, but parametrized by a higher order function which+-- constructs a list of Haskell decls to splice into scope for each PADS+-- metadata and data declaration. Namely the /type/, /newtype/, and /data/ PADS+-- constructs get passed into /derivation/ as a template haskell declaration.+--+-- PADS only supports quasiquotes in place of a Haskell declaration+-- (expressions, patterns, and types produce errors).+padsDerivation :: Derivation -> QuasiQuoter+padsDerivation derivation = QuasiQuoter+ (\s -> pparseExp s >>= (pure . fst))+ (error "parse pattern")+ (error "parse type")+ (\s -> pparseDecl derivation s >>= (pure . fst))++-- | Just the declaration parser for a PADS quasiquotation. Glues together+-- 'P.parsePadsDecls' and 'make_pads_declarations', the parser and code+-- generator.+pparseDecl :: Derivation -> String -> Q ([Dec], [PadsDecl])+pparseDecl derivation input = do+ loc <- location+ let fileName = loc_filename loc+ let (line,column) = loc_start loc+ case P.parsePadsDecls fileName line column input of+ Left err -> unsafePerformIO $ fail $ show err+ Right padsDecls ->+ do result <- make_pads_declarations' derivation padsDecls+ pure (result, padsDecls)++-- | Just the declaration parser for a PADS quasiquotation. Glues together+-- 'P.parsePadsDecls' and 'make_pads_declarations', the parser and code+-- generator.+pparseExp :: String -> Q (Exp, [PadsDecl])+pparseExp input = do+ loc <- location+ let fileName = loc_filename loc+ let (line,column) = loc_start loc+ case P.parsePadsDecls fileName line column input of+ Left err -> unsafePerformIO $ fail $ show err+ Right padsDecls -> do+ result <- make_pads_asts padsDecls+ pure (result, padsDecls)++-- | Extensible PADS quasiquoter+padsE :: ([PadsDecl] -> Q [Dec]) -> QuasiQuoter+padsE fncn = QuasiQuoter+ (\s -> pparseExp s >>= (pure . fst))+ (error "parse pattern")+ (error "parse type")+ (\s -> pparseDecl (const $ return []) s >>= \(result,ast) -> (liftM (result ++)) (fncn ast))+
@@ -0,0 +1,20 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-|+ Module : Language.Pads.RegExp+ Description : Pads regular expressions+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.RegExp where+import Data.Data++-- | Regular expression support. PADS uses the regex-posix package.+data RE = RE String -- ^ A regular expression printed as its match+ | REd String String -- ^ A regular expression printed as the second arg+ deriving (Eq, Data, Typeable, Show)+
@@ -0,0 +1,566 @@+{-# LANGUAGE NamedFieldPuns, RecordWildCards, DeriveDataTypeable #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Source+ Description : Host language representation of data input+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental+-}++module Language.Pads.Source where++import qualified Data.ByteString as B -- abstraction for input data+import qualified Text.Regex.Posix as TRP+import Language.Pads.RegExp -- user-specified regular expressions+import Text.PrettyPrint.Mainland as PP+import Text.PrettyPrint.Mainland.Class++import Data.Int+import Data.Data+import Data.Word+import Data.Char+import Data.Bits (shiftR, shiftL, (.&.))+import qualified Data.ByteString.Char8 as Char8++type RawStream = B.ByteString -- This is the type that should be used in other files!!!++{-| Input source abstraction -}+data Source = Source+ { current :: B.ByteString -- ^ The current input before EOR+ , rest :: B.ByteString -- ^ The rest of the input after the next EOR+ , loc :: Loc -- ^ The current location 'Loc' in the input+ , bit :: Int -- ^ Bit offset into the current input being parsed+ , disc :: RecordDiscipline -- ^ The record discipline of this input source+ , eorAtEOF :: Bool -- ^ Relevant for seperator-based record disciplines: Single, Multi+ -- Set when current record is last record and separtor appeared at end.+ }++-- | A record discipline specifies the manner by which pads should partition the+-- input into records. Note that the record character gets consumed internally+-- by the parsing monad.+data RecordDiscipline =+ Single Word8 -- ^ Split input based on a single 8-bit unsigned integer (character)+ | Multi B.ByteString -- ^ Split input based on more than one character+ | Bytes Int -- ^ Split the input into records every 'Int' characters+ | NoPartition -- ^ No partitioning of the input - all input data is in the 'current' field+ | NoDiscipline -- ^ No discipline is currently installed; all input data is in 'rest' field++-- | Record discipline for Unix newlines+newline = Single (chrToWord8 '\n')+-- | Record discipline for Windows CRLF newlines+windows = Multi (B.pack (strToWord8s "\r\n"))+-- | Record discipline for every n characters+bytes n = Bytes n+-- | No record discipline+none = NoPartition++{-| Source location information. -}+data Loc = Loc+ { recordNumber :: Int64 -- ^ Number of records parsed so far (i.e. record index)+ , byteOffset :: Int64 -- ^ Total number of bytes parsed into the source input so far+ } deriving (Typeable, Data,Eq, Ord, Show)++-- | A span in the source input, covering a contiguous range of the 'Source'+-- input. AFAIK there's no distinction between the states where @begin == end@+-- and where @end == Nothing@.+data Span = Span+ { begin :: Loc -- ^ Start location of the 'Span'+ , end :: Maybe Loc -- ^ End location of the 'Span', inclusive+ } deriving (Typeable, Data, Eq, Ord, Show)++-- | Initial instance of a 'Loc'+zeroLoc = Loc {recordNumber = 0, byteOffset = 0}++-- | A span starting at the beginning of the file and containing nothing.+zeroSpan = locToSpan zeroLoc++-- | Parse the most significant bit in a byte first+zeroBit = 7++-- | Increment how many records have been seen in the given 'Loc'+incRecordNumber :: Loc -> Loc+incRecordNumber Loc{recordNumber, ..} = Loc{ recordNumber = recordNumber+1+ , byteOffset = 0}++-- | Decrement how many records have been seen in the given 'Loc'+decLineNumber :: Loc -> Loc+decLineNumber Loc{recordNumber, ..} = Loc{recordNumber=recordNumber-1, byteOffset=0}++-- | Increment the offset of the 'Loc' by one+incOffset :: Loc -> Loc+incOffset l@Loc{byteOffset} = l { byteOffset = byteOffset + 1 }++-- | Increment the offset of the given 'Loc' by some number+incOffsetBy :: Loc -> Int -> Loc+incOffsetBy l@Loc{byteOffset} n = l { byteOffset = byteOffset + fromIntegral n }++-- | Decrement the offset of the given 'Loc' by one+decOffset :: Loc -> Loc+decOffset l@Loc{byteOffset} = l { byteOffset = byteOffset - 1 }++getSrcLoc :: Source -> Loc+getSrcLoc = loc++getRecordDiscipline :: Source -> RecordDiscipline+getRecordDiscipline = disc+++-------------------------------------------------------------------------------+-- * Source Creation++-- | An empty Source with reasonable defaults for everything.+emptySource = Source+ { current = B.empty+ , rest = B.empty+ , loc = zeroLoc+ , bit = zeroBit+ , eorAtEOF = False+ , disc = newline+ }++-- | Stuff the given 'String' into a 'Source' with a newline discipline by+-- default (see 'padsSourceFromByteString')+padsSourceFromString :: String -> Source+padsSourceFromString str = padsSourceFromByteString (strToByteString str)++-- | Stuff the given 'String' into a 'Source' with the given record discipline+padsSourceFromStringWithDisc :: RecordDiscipline -> String -> Source+padsSourceFromStringWithDisc d str = padsSourceFromByteStringWithDisc d (strToByteString str)++-- | Read a 'Source' from disk+padsSourceFromFile :: FilePath -> IO Source+padsSourceFromFile file = do+ bs <- B.readFile file+ return (padsSourceFromByteString bs)++-- | Read a 'Source' from disk using the given record discipline+padsSourceFromFileWithDisc :: RecordDiscipline -> FilePath -> IO Source+padsSourceFromFileWithDisc d file = do+ bs <- B.readFile file+ return (padsSourceFromByteStringWithDisc d bs)++-- | Construct a 'Source' from the given 'ByteString', preparing the first+-- record immediately.+padsSourceFromByteString :: B.ByteString -> Source+padsSourceFromByteString bs =+ let rawSource = Source{ current = B.empty+ , rest = bs+ , loc = zeroLoc+ , bit = zeroBit+ , disc = newline+ , eorAtEOF = False+ }+ in getNextRecord rawSource++-- | Same as 'padsSourceFromByteString' but with a record discipline+padsSourceFromByteStringWithDisc :: RecordDiscipline -> B.ByteString -> Source+padsSourceFromByteStringWithDisc d bs =+ let rawSource = Source{ current = B.empty+ , rest = bs+ , loc = zeroLoc+ , bit = zeroBit+ , disc = d+ , eorAtEOF = False+ }+ in getNextRecord rawSource++-- | Whether or not the 'Source' has consumed all available input+isEOF :: Source -> Bool+isEOF (s @ Source{current, rest, eorAtEOF, ..}) = B.null current && B.null rest && not eorAtEOF++-- | Whether or not the 'Source' has consumed all input in the current record+isEOR :: Source -> Bool+isEOR = B.null . current++-------------------------------------------------------------------------------+-- * Record Manipulating Functions+{- Called when current is empty to get the next record, where the disc field defines what constitutes a record.+ NOOP when isEOF is already true. -}+getNextRecord :: Source -> Source+getNextRecord (s @ Source {current, rest, loc, bit, disc, eorAtEOF}) =+ if isEOF s then s+ else if eorAtEOF || B.null rest then+ (Source {current = B.empty, rest = B.empty, loc = incRecordNumber loc, bit = zeroBit, disc, eorAtEOF = False})+ else (Source {current = nextLine, rest=residual, loc = incRecordNumber loc, bit = zeroBit, disc, eorAtEOF = eorAtEOF'}) --TODO: is this bit positioning sound?+ where (nextLine, residual, eorAtEOF') = breakUsingDisc rest disc++srcLineBegin :: Source -> (Maybe String, Source)+srcLineBegin s = (Nothing, s)++srcLineEnd :: Source -> (Maybe String, Source)+srcLineEnd s = if isEOF s+ then (Just "Found EOF when looking for EOR", s)+ else (Nothing, getNextRecord s)++{- External code should not set discipline to NoDiscipline; that is an internal state only to+ mark state between two legal external disciplines. -}+setRecordDiscipline :: RecordDiscipline -> Source -> ((),Source)+setRecordDiscipline r s =+ let s' = unputCurrentLine s+ s'' = s'{disc = r}+ in ((),getNextRecord s'')++{- Merge current record back on to rest according to current record discipline.+ Resulting source will be in NoDiscipline state.+ Noop if called at EOF.+-}+unputCurrentLine :: Source -> Source+unputCurrentLine (s @ Source {current, rest, loc, disc, eorAtEOF}) =+ if isEOF s then s+ else case disc of+ Single n -> let rest' = if B.null rest+ then if eorAtEOF+ then B.concat [current, B.singleton n]+ else current+ else B.concat [current, B.singleton n, rest]+ loc' = if B.null current then loc else decLineNumber loc+ in Source {current = B.empty, rest = rest', loc = loc', bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}+ Multi br -> let rest' = if B.null rest+ then if eorAtEOF+ then B.concat [current, br]+ else current+ else B.concat [current, rest]+ loc' = if B.null current then loc else decLineNumber loc+ in Source {current = B.empty, rest = rest', loc = loc', bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}+ Bytes n -> Source {current = B.empty, rest = B.append current rest, loc = decLineNumber loc, bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}+ NoPartition -> Source {current = B.empty, rest = current, loc = decLineNumber loc, bit = zeroBit, disc = NoDiscipline, eorAtEOF = False}+ NoDiscipline -> s+++breakUsingDisc :: B.ByteString -> RecordDiscipline -> (B.ByteString, B.ByteString, Bool)+breakUsingDisc bs rd = case rd of+ Single n -> let (nextLine, raw_residual) = B.break (\c->c == n) bs+ residual = B.drop 1 raw_residual+ eorAtEOF = (B.null residual) && (not $ B.null raw_residual)+ in (nextLine, residual, eorAtEOF)+ Multi s -> let (nextLine, raw_residual) = B.breakSubstring s bs+ residual = B.drop (B.length s) raw_residual+ eorAtEOF = (B.null residual) && (not $ B.null raw_residual)+ in (nextLine, residual, eorAtEOF)+ Bytes n -> let (nextLine, residual) = B.splitAt n bs+ in (nextLine, residual, False)+ NoPartition -> (bs, B.empty, False)+ NoDiscipline -> error "Pads Source: Attempt to partition source using internal discipline 'NoDiscipline'"++-------------------------------------------------------------------------------+-- * Converting Sources to Strings+--+padsSourceToString :: Source -> String+padsSourceToString = (map word8ToChr) . B.unpack . padsSourceToByteString++padsSourceToByteString :: Source -> B.ByteString+padsSourceToByteString = rest . unputCurrentLine++drainSource :: Source -> (String, Source)+drainSource s = (padsSourceToString s, emptySource)++drainSourceNB :: Source -> (String, Source)+drainSourceNB (s @ Source{current,loc, ..}) =+ let len = (B.length current) - (if bit == zeroBit then 0 else 1)+ (bs, s') = takeBits (len * 8) s+ in (map word8ToChr (numToWord8s bs []), emptySource)+++{- XXX: Change call site to use no record discipline; then this call should just became an instance of drainSource -}+rawSource :: Source -> (B.ByteString, Source)+rawSource s = (padsSourceToByteString s, emptySource)++{- Return the rest of the current record as a string -}+restRec :: Source -> String+restRec = byteStringToStr . current++-------------------------------------------------------------------------------+-- * Operations within a single record+head :: Source -> Char+head = word8ToChr . headOrZero . current++headOrZero s = if B.null s then chrToWord8 '\0' else B.head s++peekHeadM :: Source -> (Maybe Char, Source)+peekHeadM (s @ Source{current,loc, ..}) =+ if B.null current then (Nothing, s) else (Just (Language.Pads.Source.head s), s)++takeHead :: Source -> (Char, Source)+takeHead (s @ Source{current,loc, ..}) =+ (word8ToChr $ B.head current, s{current = B.tail current, loc = incOffset loc})++partitionBS :: Integral a => B.ByteString -> a -> a -> (B.ByteString, B.ByteString, Bool)+partitionBS bS bitIndex bits =+ let part b bs = if bs > b + 1 then 1 + part zeroBit (bs - (b + 1)) else 1+ byteAlign = (bits - (bitIndex + 1)) `mod` 8 == 0+ withinByte = bits <= bitIndex + 1+ hd = B.take (part (fromIntegral bitIndex) (fromIntegral bits)) bS+ tl = B.drop (B.length hd - if not byteAlign then 1 else 0) bS+ in (hd, tl, withinByte || not byteAlign)++accumulate :: Integral a => a -> (a, Int) -> (a, Int)+accumulate byte (num, pow) = ((byte * (256 ^ pow)) + num, pow + 1)++takeBits8 :: Integral a => a -> Source -> (Word8, Source)+takeBits8 b (s @ Source{current,loc,bit, ..}) =+ let (hd, tl, partial) = partitionBS current bit (fromIntegral b)+ bS = map (\x -> fromIntegral x :: Word16) (B.unpack $ B.take 2 hd)+ bytes = fst $ foldr accumulate (0,0) bS+ mask = (2 ^ b) - 1+ bits = mask .&. shiftR bytes ((B.length hd * 8) - (fromIntegral b) - (zeroBit - bit))+ in (fromIntegral bits, s{current = tl,+ loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),+ bit = (zeroBit - (((zeroBit - bit) + (fromIntegral b)) `mod` 8))})++takeBits16 :: Integral a => a -> Source -> (Word16, Source)+takeBits16 b (s @ Source{current,loc,bit, ..}) =+ let (hd, tl, partial) = partitionBS current bit (fromIntegral b)+ bS = map (\x -> fromIntegral x :: Word32) (B.unpack $ B.take 3 hd)+ bytes = fst $ foldr accumulate (0,0) bS+ mask = (2 ^ b) - 1+ bits = mask .&. shiftR bytes ((B.length hd * 8) - (fromIntegral b) - (zeroBit - bit))+ in (fromIntegral bits, s{current = tl,+ loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),+ bit = (zeroBit - (((zeroBit - bit) + (fromIntegral b)) `mod` 8))})++takeBits32 :: Integral a => a -> Source -> (Word32, Source)+takeBits32 b (s @ Source{current,loc,bit, ..}) =+ let (hd, tl, partial) = partitionBS current bit (fromIntegral b)+ bS = map (\x -> fromIntegral x :: Word64) (B.unpack $ B.take 5 hd)+ bytes = fst $ foldr accumulate (0,0) bS+ mask = (2 ^ b) - 1+ bits = mask .&. shiftR bytes ((B.length hd * 8) - (fromIntegral b) - (zeroBit - bit))+ in (fromIntegral bits, s{current = tl,+ loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),+ bit = zeroBit - (((zeroBit - bit) + (fromIntegral b)) `mod` 8)})++takeBits64 :: Integral a => a -> Source -> (Word64, Source)+takeBits64 b s = let (bits, s') = takeBits b s+ in (fromIntegral bits, s')++tobinary :: Integer -> Integer+tobinary x+ | (div x 2) == 0 = x+ | otherwise = (mod x 2) + (10 * (tobinary $ div x 2))++takeBits :: Integral a => a -> Source -> (Integer, Source)+takeBits b (s @ Source{current,loc,bit, ..}) =+ let (hd, tl, partial) = partitionBS current bit (fromIntegral b)+ bS = map fromIntegral (B.unpack hd)+ bytes = fst $ foldr accumulate (0,0) bS+ mask = (2 ^ b) - 1+ shiftAmt = max 0 ((B.length hd * 8) - (fromIntegral b) - (zeroBit - bit))+ bits = mask .&. shiftR bytes shiftAmt+ in (bits, s{current = tl,+ loc = incOffsetBy loc (B.length hd - if partial then 1 else 0),+ bit = zeroBit - (((zeroBit - bit) + (fromIntegral b)) `mod` 8)})++takeHeadM :: Source -> (Maybe Char, Source)+takeHeadM (s @ Source{current,loc, ..}) =+ if B.null current then (Nothing, s)+ else (Just $ word8ToChr $ B.head current, s{current = B.tail current, loc = incOffset loc})++-- | If the front of the current source input matches the given string then+-- remove it and return the modified source. Otherwise return the original+-- source and a boolean flag indicating that we failed to take the given string+-- off the front of the source input.+takeHeadStr :: String -> Source -> (Bool, Source)+takeHeadStr str s =+ let pstr = strToByteString str+ in if B.isPrefixOf pstr (current s)+ then let (res,source) = Language.Pads.Source.take (B.length pstr) s+ in (True, source)+ else (False, s)+++matchString :: String -> Source -> Maybe(String, Source)+matchString str s =+ let pstr = strToByteString str+ in if B.isPrefixOf pstr (current s)+ then let (res,source) = Language.Pads.Source.take (B.length pstr) s+ in Just(str, source)+ else Nothing+++breakSubstring :: B.ByteString -- ^ String to search for+ -> B.ByteString -- ^ String to search in+ -> (B.ByteString,B.ByteString) -- ^ Head and tail of string broken at substring+breakSubstring pat src = search 0 src+ where+ -- STRICT2(search)+ search :: Int -> B.ByteString -> (B.ByteString, B.ByteString)+ search a b | a `seq` b `seq` False = undefined+ search n s+ | B.null s = (src,B.empty) -- not found+ | pat `B.isPrefixOf` s = (B.take n src,s)+ | otherwise = search (n+1) (B.tail s)++{-|+ Scan the current source input until we find the given string:+ - If we don't find the string return Nothing and leave source unmodified+ - If we return (Maybe []), then we found the string at the beginning of the+ source and removed it.+ - If we return (Maybe junk), then we found the string somewhere after the+ first character in the source and we consumed / removed (junk:str).+-}+scanStr :: String -> Source -> (Maybe String, Source)+scanStr str (s @ Source{current,loc, ..}) =+ let pat = strToByteString str+ (before,after) = breakSubstring pat current+ in if B.null after then (Nothing, s)+ else let len = B.length pat+ in (Just (byteStringToStr before),+ s{current = B.drop len after, loc = incOffsetBy loc len})+++scanString :: String -> Source -> Maybe (String, Source)+scanString str (s @ Source{current,loc, ..}) =+ let pat = strToByteString str+ (before,after) = breakSubstring pat current+ in if B.null after then Nothing+ else let len = B.length pat+ in Just (byteStringToStr before, s{current= B.drop len after, loc = incOffsetBy loc len})++satisfyNB :: (Char -> Bool) -> Source -> (String, Source)+satisfyNB p s =+ let (c, s') = takeBits8 8 s+ c' = word8ToChr c+ in if p c'+ then (c' : (fst $ satisfyNB p s'), snd $ satisfyNB p s')+ else ([], s)++takeBytes :: Int -> Source -> (B.ByteString, Source)+takeBytes n (s @ Source{current,loc, ..}) =+ let (head, tail) = B.splitAt n current+ incOffset = B.length head+ in (head, s{current= tail, loc = incOffsetBy loc incOffset})++takeBytesNB :: Int -> Source -> (B.ByteString, Source)+takeBytesNB n s =+ let (bits, s') = takeBits (n * 8) s+ numToBS x = B.pack $ numToWord8s x []+ in (numToBS bits, s')++numToWord8s :: Integral a => a -> [Word8] -> [Word8]+numToWord8s x accum+ | x < 256 = fromIntegral x : accum+ | otherwise = numToWord8s (x `div` 256) (fromIntegral (x `mod` 256) : accum)++take :: Int -> Source -> (String, Source)+take n s = let (bs, s') = takeBytes n s+ in (byteStringToStr bs, s')++-- | Match the beginning of the source input with a regex, returning a tuple of+-- the matched string and the modified source with that string removed.+regexMatch :: RE -> Source -> (Maybe String, Source)+regexMatch (RE re_str_raw) (s @ Source{current,loc,..}) =+ let (before, match, after) = current TRP.=~ (strToByteString('^' : re_str_raw))+ in if not (B.null before) then (Nothing, s) -- only looking for matches at the beginning of the string+ else (Just (byteStringToStr match), s{current=after, loc=incOffsetBy loc (fromIntegral (B.length match))})+regexMatch (REd re_str_raw def ) s = regexMatch (RE re_str_raw) s++-- | Find the first match of a regex in the source input, returning the contents+-- of the source input *before* the match.+-- * If there's no match return Nothing and leave the source unmodified.+-- * If there's a match, return the string before the match and remove *just*+-- the string before from the source input.+regexStop :: RE -> Source -> (Maybe String, Source)+regexStop (RE re_str_raw) (s @ Source{current,loc,..}) =+ let packed = strToByteString re_str_raw+ (before, match, after) = current TRP.=~ packed -- Is there a way to test this result matches w/o duplicating match?+ isMatch = current TRP.=~ packed+ in if not isMatch+ then (Nothing, s) -- match failed, return input unchanged+ else (Just (byteStringToStr before),+ s{current= B.append match after,loc=incOffsetBy loc (fromIntegral (B.length before))})++-- | See 'regexStop'+regexStop (REd re_str_raw def) s = regexStop (RE re_str_raw) s++-- | Remove and return the longest prefix of the source input satisfying the+-- given predicate.+span p (s @ Source{current,loc,..}) =+ let (head, tail) = B.span p current+ incOffset = B.length head+ in (B.unpack head, s{current=tail, loc = incOffsetBy loc incOffset})++-- | Same as 'span' but for predicates over type 'Char'.+whileS :: (Char -> Bool) -> Source -> Maybe (String,Source)+whileS p (s @ Source{current,loc,..}) =+ let (head, tail) = B.span (p . word8ToChr) current+ incOffset = B.length head+ in Just (byteStringToStr head, s{current=tail, loc=incOffsetBy loc incOffset})++-- | Remove the first byte of the input source.+tail (s @ Source{current,loc,..}) =+ (s{current=B.tail current,loc=incOffset loc})++-- | Scan the input source until we find the given character. If we don't find+-- the character indicate as such with the boolean (False) and remove all source+-- input from the current record. If we do find the character, return True and+-- consume input up to and including the matched character. The 'Span' in the+-- returned tuple indicates the region in the input that got scanned and removed+-- by this function (whether or not we failed to find the character).+scanTo :: Char -> Source -> (Bool, Source, Span)+scanTo chr (src @ Source{current,loc, ..}) =+ let begin = getSrcLoc src+ (skipped, residual) = B.break (\c->c== (chrToWord8 chr)) current+ (found,remaining,incAmount) =+ if B.null residual then -- Reached EOR w/o finding chr+ (False, residual, B.length skipped)+ else (True, B.tail residual, (B.length skipped) + 1)+ newLoc = incOffsetBy loc incAmount+ endErrLoc = incOffsetBy loc (B.length skipped)+ in (found,+ src {current = remaining, loc=newLoc},+ Span {begin, end=Just endErrLoc})+++lift :: (String -> [(a, String)]) -> (Source -> (Maybe a, Source))+lift f s = case f (byteStringToStr $ current s) of+ [] -> (Nothing, s)+ (x,residual):rest -> (Just x, s{current= (strToByteString residual)})++{- Helper routines -}++eqCurrent :: Source -> Source -> Bool+eqCurrent s s'= current s == current s'++chrToWord8 :: Char -> Word8+chrToWord8 c = toEnum $ fromEnum c++strToWord8s :: String -> [Word8]+strToWord8s = map chrToWord8++word8ToChr :: Word8 -> Char+word8ToChr = toEnum . fromEnum++word8sToStr :: [Word8] -> String+word8sToStr = map word8ToChr++byteStringToStr :: B.ByteString -> String+byteStringToStr = word8sToStr . B.unpack++strToByteString :: String -> B.ByteString+--strToByteString = B.pack . strToWord8s+strToByteString = Char8.pack++++locToSpan :: Loc -> Span+locToSpan loc = Span { begin = loc, end = Nothing }++locsToSpan :: Loc -> Loc -> Span+locsToSpan b e = Span {begin = b, end = Just e}++-------------------------------------------------------------------------------+-- * Pretty print sources+instance Pretty Source where+ ppr (Source{current, rest, ..}) = text "Current:" <+> text (show current)++instance Pretty Loc where+ ppr (Loc{recordNumber,byteOffset}) = text "Line:" <+> ppr recordNumber <> text ", Offset:" <+> ppr byteOffset++instance Pretty Span where+ ppr (Span{begin,end}) = case end of+ Nothing -> ppr begin+ Just end_loc -> text "from:" <+> ppr begin <+> text "to:" <+> ppr end_loc
@@ -0,0 +1,189 @@+{-# LANGUAGE DeriveDataTypeable,DeriveLift, DeriveAnyClass, DeriveGeneric #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.Syntax+ Description : The concrete syntax of Pads in Haskell+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++ Haskell data types, instances, and helper functions over these types for the+ syntax of Pads.++-}+module Language.Pads.Syntax where++import Data.Generics (Data(..), Typeable(..))+import Language.Haskell.TH+import Language.Haskell.TH.Lift (Lift(..))+import GHC.Generics (Generic(..))++instance Lift Pat+instance Lift Exp++-- | AST form of a pads declaration with four flavors.+data PadsDecl+ -- | A pads type declaration e.g.:+ --+ -- > [pads| type Foo x y z (foo :: Int) = (x, y, z, foo) generator <|gen|> |]+ = PadsDeclType String [String] (Maybe Pat) PadsTy (Maybe Exp)++ -- | A pads data declaration e.g.:+ --+ -- > [pads| data Foo x y z (foo :: Int) = Foo (x, y, z, foo) deriving (Eq, Ord, Show) |]+ | PadsDeclData String [String] (Maybe Pat) PadsData [QString]++ -- | A pads newtype declaration e.g.:+ --+ -- > [pads| newtype Foo x y z (foo :: Int) = Foo (x, y, z, foo) deriving (Eq, Ord, Show) |]+ | PadsDeclNew String [String] (Maybe Pat) BranchInfo [QString]++ -- | A pads declaration for obtaining one type after parsing it from another, e.g.:+ --+ -- > [pads| obtain Foo x y z from Int using <|(fncn,inverse)|> generator <|gen|> |]+ | PadsDeclObtain String [String] PadsTy Exp (Maybe Exp)+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | AST form of a pads type, as notably used to the right hand side of an+-- equals sign in a @'PadsDecl'@ pads declaration.+data PadsTy+ -- | AST form of "constrain @'Pat'@ :: @'PadsTy'@ where @'Exp'@" e.g.:+ --+ -- > [pads| constrain x :: Digit where <|x `mod` 2|> == 0|> |]+ = PConstrain Pat PadsTy Exp++ -- | AST form of "transform @'PadsTy'@ => @'PadsTy'@ using @'Exp'@" e.g.:+ --+ -- > [pads| transform StringFW 1 => Char using <|(head, list1)|> |]+ | PTransform PadsTy PadsTy Exp (Maybe Exp)++ -- | AST form of a list of some @'PadsTy'@ type, comes with two optional attributes e.g.:+ -- "[ @'PadsTy'@ | @'PadsTy'@ ] terminator @'TermCond'@"+ --+ -- The following @'PadsTy'@ describes a comma-separated list of integers+ -- terminated by the EOF symbol:+ --+ -- > [pads| [Int | ','] terminator EOF |]+ | PList PadsTy (Maybe PadsTy) (Maybe TermCond)++ -- | AST form of a partitioned type "partition @'PadsTy'@ using @'Exp'@" e.g.:+ --+ -- > [pads| partition Entries using <| bytes 6 |> |]+ --+ -- A partitioned type allows for parser extensions to make use of the state of+ -- the PADS parser in deciding how to divide up (partition) the input.+ | PPartition PadsTy Exp++ -- | AST form of a value constructor "value @'Exp'@ :: @'PadsTy'@" e.g.:+ --+ -- > [pads| data Foo = Foo { x :: Int, xIsEven = value <| even x |> :: Bool } |]+ --+ -- This allows you to do the opposite of what @'BConstr'@ does: bring names into+ -- scope which get stored in the output of the parser (rather than having them+ -- disappear after the parser finishes.+ | PValue Exp PadsTy++ -- | A pads type application like "@'PadsTy'@ @'PadsTy'@ @'PadsTy'@ ... @'Exp'@" e.g.+ --+ -- > [pads| data Foo = Foo { x :: Int, Bar x <| x + 1 |> |]+ | PApp [PadsTy] (Maybe Exp)++ -- | AST form of a pads tuple "( @'PadsTy@', @'PadsTy@', ... )" e.g.+ --+ -- > [pads| (Int, "+", Int) |]+ | PTuple [PadsTy]++ -- | An arbitrary Haskell expression as used in a @'PApp'@ pads type application+ -- and in a @'PSwitch'@ pads switch/case type.+ | PExpression Exp++ -- | Pads type constructor with a qualified name+ | PTycon QString++ -- | Pads type variable with a name+ | PTyvar String+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | Parser terminator condition+data TermCond+ -- | Lexical terminator type: any @'PadsTy'@ signaling termination+ = LTerm PadsTy++ -- | Lexical length: arbitrary Haskell @'Exp@'+ | LLen Exp+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | Right-hand side of a pads data type declaration+data PadsData+ -- | A pads union data type declaration.+ -- Syntax: "@'BranchInfo'@ | @'BranchInfo'@ | ..."+ = PUnion [BranchInfo]++ -- | A pads switch-case 'statement'.+ --+ -- Syntax:+ --+ -- @+ -- case 'Exp' of+ -- 'Pat' -> 'BranchInfo'+ -- | 'Pat' -> 'BranchInfo'+ -- ...+ -- @+ --+ -- > [pads| case <| tag + 1 |> of+ -- > 2 -> Foo+ -- > | 3 -> Bar+ -- > |]+ | PSwitch Exp [(Pat,BranchInfo)]+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | An individual branch of some pads data type, either defining a Haskell record+-- parser or a Haskell constructor parser.+data BranchInfo+ -- | Branch record with a constructor name, list of record fields, and maybe a boolean 'where' clause.+ --+ -- Syntax: @'String'@ { @'FieldInfo'@, @'FieldInfo'@, ... } where @'Exp@'+ --+ -- > [pads| Foo { x :: Int, y :: Char } where <| x == ord y |>+ = BRecord String [FieldInfo] (Maybe Exp)++ -- | Branch constructor with a constructor name, a list of argument types, and maybe a boolean 'where' clause:+ --+ -- Syntax: @'String'@ @'ConstrArg'@ @'ConstrArg'@ ... where @'Exp@'+ --+ -- > [pads| Foo (x :: Int) (y :: Char) where <| x == ord y |>+ --+ -- Note that this lets you bring variables into scope during parsing (`x` and+ -- `y` in the above) *without* saving them into the parse result, effectively+ -- making them operate as temporary variables that can be referenced by the+ -- Haskell predicates.+ | BConstr String [ConstrArg] (Maybe Exp)+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | Individual field of a pads record, "@'String'@ :: @'ConstrArg'@ where @'Exp'@"+type FieldInfo = (Maybe String, ConstrArg, Maybe Exp, Maybe Exp)+type ConstrArg = (PadsStrict, PadsTy)++-- | A hold-over resulting from a deprecation moving from an older version of template-haskell.+data PadsStrict = IsStrict | NotStrict | Unpacked+ deriving (Eq, Data, Typeable, Show, Lift, Generic)++-- | Qualified names where ["Foo", "Bar"] means "Foo.Bar"+type QString = [String]++-- | Whether or not a @'PadsTy'@ has an underlying Haskell representation+hasRep :: PadsTy -> Bool+hasRep (PExpression l) = False+hasRep (PTycon ["EOF"]) = False+hasRep (PTycon ["EOR"]) = False+hasRep (PTycon ["Void"]) = False+hasRep (PApp [PTycon ["Try"], t] _) = hasRep t+hasRep ty = True++-- | > ["Foo", "Bar"] -> "Foo.Bar"+qName :: QString -> String+qName [n] = n+qName (n:ms) = n ++ "." ++ qName ms
@@ -0,0 +1,163 @@+{-# LANGUAGE TemplateHaskell, MagicHash #-}+{-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_HADDOCK prune #-}+{-|+ Module : Language.Pads.TH+ Description : Template Haskell utilities+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.TH where++import Language.Haskell.TH as TH+import Language.Haskell.TH.Syntax+import Control.Monad+import Data.Char+import GHC.Exts++typeAnnotate :: Maybe TH.Pat -> Maybe (TH.Pat, TH.Type)+typeAnnotate Nothing = Nothing+typeAnnotate (Just pat) = Just (pat, patToTy pat)++mergeMaybe :: Maybe a -> Maybe b -> Maybe (a,b)+mergeMaybe m1 m2 = case (m1,m2) of+ (Nothing, Nothing) -> Nothing+ (Just d1, Just d2) -> Just (d1,d2)+ _ -> error "mergeMaybe given two maybes in different states."++mapFstChar :: (Char -> Char) -> String -> String+mapFstChar _ [] = []+mapFstChar f (c:cs) = f c : cs++strToUpper, strToLower :: String -> String+strToUpper = mapFstChar toUpper+strToLower = mapFstChar toLower++applyE :: [Exp] -> Exp+applyE ts = foldl1 AppE ts++applyT :: [Type] -> Type+applyT ts = foldl1 AppT ts++abstractT :: Type -> [Type] -> Type+abstractT t ts = foldr arrow t ts+ where+ t1 `arrow` t2 = (ArrowT `AppT` t1) `AppT` t2++arrowTy :: Type -> Type -> Type+arrowTy ty1 ty2 = (ArrowT `AppT` ty1) `AppT` ty2+++mkListT, mkTupleT :: [Type] -> Type+mkListT ts = foldl AppT ListT ts+mkTupleT ts = foldl AppT (TupleT (length ts)) ts++listTH, tupleTH :: [Name] -> Q Exp+listTH xs = return (ListE (map VarE xs))+tupleTH xs = return (TupE (map VarE xs))++++tupleTyToListofTys :: Type -> (Int,[Type])++-- for tuples encoded as AppT (,) (AppT a b)+tupleTyToListofTys (AppT (TupleT n) ty0) = (n, collect ty0)+ where+ collect ty = case ty of+ AppT ty' tys' -> ty' : collect tys'+ _ -> [ty]++-- for tuples encoded as AppT (AppT (,) a) b+tupleTyToListofTys ty0 = collect ty0 []+ where+ collect ty acc = case ty of+ TupleT n -> (n, acc)+ AppT tys ty' -> collect tys (ty':acc)+ _ -> error "typeleTyToListofTys: unexpected type"++genPE :: Name -> (Exp,Pat)+genPE name = (VarE name, VarP name)++genPEQ :: Name -> (Q Exp, Q Pat)+genPEQ name = (return (VarE name), return (VarP name))++doGenPE :: String -> Q (Exp,Pat)+doGenPE str = do {+ ; name <- newName str+ ; return (VarE name, VarP name)+ }++doGenPEs :: Int -> String -> Q([TH.Exp], [TH.Pat])+doGenPEs n str = do+ { varpats <- replicateM n (doGenPE str)+ ; return (unzip varpats)+ }++{- XXX: need to add location information so can report location of error messages. -}+patToTy :: TH.Pat -> TH.Type+patToTy pat = case pat of+ LitP l -> litToTy l+ VarP n -> error ("Variable "++ (showName n) ++ " needs a type annotation.")+ TupP pats -> mkTupleT (map patToTy pats)+ InfixP _ n _ -> error ("Infix constructor "++ (showName n) ++ " application needs a type annotation.")+ TildeP p -> patToTy p+ BangP p -> patToTy p+ AsP _ p -> patToTy p+ WildP -> error "Wild card patterns are not supported in PADS declarations."+ {- I think this is the correct represtentation of a line type. -}+ RecP name _fieldPats -> ConT name+ ListP pats -> mkListT (map patToTy pats)+ SigP _ ty -> ty+ ParensP pat' -> patToTy pat'+ _ -> error ("patToTy: unexpected pat: " ++ show pat)++litToTy :: TH.Lit -> TH.Type+litToTy lit = ConT $ case lit of+ CharL _ -> ''Char+ StringL _ -> ''String+ IntegerL _ -> ''Integer+ RationalL _ -> ''Rational+ IntPrimL _ -> ''Integer+ WordPrimL _ -> ''Integer+ FloatPrimL _ -> ''Rational+ DoublePrimL _ -> ''Rational+ _ -> error ("litToTy: unexpected lit: " ++ show lit)++patToExp :: TH.Pat -> TH.Exp+patToExp pat = case pat of+ LitP l -> LitE l+ VarP n -> VarE n+ TupP pats -> TupE (map patToExp pats)+ InfixP p1 n p2 -> InfixE (Just (patToExp p1)) (VarE n) (Just (patToExp p2))+ TildeP p -> patToExp p+ BangP p -> patToExp p+ AsP n _ -> VarE n+ WildP -> error "Wild card patterns are not supported in PADS declarations. Can't convert to expression"++ {- I think this is the correct represtentation of a line type. -}+ RecP name fieldPats -> RecConE name (map fieldPatToExp fieldPats)+ ListP pats -> ListE (map patToExp pats)+ SigP p _ty -> patToExp p+ ParensP p -> patToExp p+ _ -> error ("patToExp: unexpected pat: " ++ show pat)++fieldPatToExp :: (a,Pat) -> (a,Exp)+fieldPatToExp (n,p) = (n, patToExp p)++boolToExpE :: Bool -> Exp+boolToExpE True = ConE 'True+boolToExpE False = ConE 'False++-- generate globally scoped unique variables as suggested in https://ghc.haskell.org/trac/ghc/ticket/5398+mangleName :: Name -> Name+mangleName name@(Name occ fl) = case fl of+ NameU (I# u) -> Name (mangle_occ occ u) fl+ _ -> name+ where+ mangle_occ :: OccName -> Int# -> OccName+ mangle_occ occ' uniq = mkOccName (occString occ' ++ "_" ++ show (I# uniq))
@@ -0,0 +1,33 @@+{-# OPTIONS_HADDOCK prune, ignore-exports #-}+{-|+ Module : Language.Pads.Testing+ Description : Pads testing utilities+ Copyright : (c) 2011+ Kathleen Fisher <kathleen.fisher@gmail.com>+ John Launchbury <john.launchbury@gmail.com>+ License : MIT+ Maintainer : Karl Cronburg <karl@cs.tufts.edu>+ Stability : experimental++-}+module Language.Pads.Testing (+ module Test.HUnit,+ mkTestCase,+ mkFileTestCase,+ mdToError,+ mdFileToError+ )+ where++import Language.Pads.Padsc+import Test.HUnit hiding (test)++mdToError ((rep,md), residual) = (rep, getTotalErrors md, residual)+mkTestCase s expected seen = TestCase(assertEqual s expected (mdToError seen))++mdFileToError (rep,md) = (rep, getTotalErrors md)+mkFileTestCase s expected seen = TestCase(assertEqual s expected (mdFileToError seen))++getTotalErrors :: PadsMD md => md -> Int+getTotalErrors md = numErrors $ get_md_header md+