First implementation of CLASSPATH and JAR files reading.
[hs-java.git] / Java / META / Parser.hs
diff --git a/Java/META/Parser.hs b/Java/META/Parser.hs
new file mode 100644 (file)
index 0000000..b27cecc
--- /dev/null
@@ -0,0 +1,60 @@
+
+module Java.META.Parser where
+
+import qualified Data.Map as M
+import Text.Parsec
+import Text.Parsec.String
+
+import Java.META.Types
+
+pNewLine :: Parser ()
+pNewLine = choice $ map try $ [
+              string "\r\n" >> return (),
+              char '\r' >> return (),
+              char '\n' >> return () ]
+
+blankline :: Parser ()
+blankline = do
+  pNewLine <?> "first newline in blankline"
+  return ()
+
+pSection :: Parser Section
+pSection = do
+  list <- many1 pHeader
+  blankline <?> "blank line"
+  return $ M.fromList list
+
+pHeader :: Parser (String, String) 
+pHeader = do
+    name <- many1 headerChar <?> "header name"
+    char ':'
+    value <- pValue
+    return (name, value)
+  where
+    headerChar = oneOf "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+
+pValue :: Parser String
+pValue = do
+  list <- manyLines
+  return (concat list)
+
+manyLines :: Parser [String]
+manyLines = do
+  char ' '
+  many space
+  s <- many1 (noneOf "\n\r\0")
+  pNewLine <?> "new line at end of value line"
+  c <- lookAhead anyChar
+  if c == ' '
+    then do
+         next <- manyLines
+         return (s: next)
+    else return [s]
+
+pMETA :: Parser META
+pMETA = many1 pSection
+
+parseMetaFile :: FilePath -> IO (Either ParseError META)
+parseMetaFile path = do
+  str <- readFile path
+  return $ parse pMETA path (str ++ "\n\n")