-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate global and workspace caches (#42)
Also use `FilePath` throughout for paths. Fixes #39
- Loading branch information
1 parent
2e27ec7
commit b593340
Showing
24 changed files
with
2,268 additions
and
1,985 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
""" | ||
# Ini package | ||
The Ini package provides support for parsing | ||
[INI file](https://en.wikipedia.org/wiki/INI_file) formatted text. | ||
* Currently _does not_ support multi-line entries. | ||
* Any keys not in a section will be placed in the section "" | ||
# Example code | ||
```pony | ||
// Parses the file 'example.ini' in the current working directory | ||
// Output all the content | ||
use "ini" | ||
use "files" | ||
actor Main | ||
new create(env:Env) => | ||
try | ||
let ini_file = File(FilePath(FileAuth(env.root), "example.ini")) | ||
let sections = IniParse(ini_file.lines())? | ||
for section in sections.keys() do | ||
env.out.print("Section name is: " + section) | ||
for key in sections(section)?.keys() do | ||
env.out.print(key + " = " + sections(section)?(key)?) | ||
end | ||
end | ||
end | ||
``` | ||
""" | ||
primitive IniIncompleteSection | ||
primitive IniNoDelimiter | ||
|
||
type IniError is | ||
( IniIncompleteSection | ||
| IniNoDelimiter | ||
) | ||
|
||
interface IniNotify | ||
""" | ||
Notifications for INI parsing. | ||
""" | ||
fun ref apply(section: String, key: String, value: String): Bool | ||
""" | ||
This is called for every valid entry in the INI file. If key/value pairs | ||
occur before a section name, the section can be an empty string. Return | ||
false to halt processing. | ||
""" | ||
|
||
fun ref add_section(section: String): Bool => | ||
""" | ||
This is called for every valid section in the INI file. Return false | ||
to halt processing. | ||
""" | ||
true | ||
|
||
fun ref errors(line: USize, err: IniError): Bool => | ||
""" | ||
This is called for each error encountered. Return false to halt processing. | ||
""" | ||
true | ||
|
||
primitive Ini | ||
""" | ||
A streaming parser for INI formatted lines of test. | ||
""" | ||
fun apply(lines: Iterator[String box], f: IniNotify): Bool => | ||
""" | ||
This accepts a string iterator and calls the IniNotify for each new entry. | ||
If any errors are encountered, this will return false. Otherwise, it | ||
returns true. | ||
""" | ||
var section = "" | ||
var lineno = USize(0) | ||
var ok = true | ||
|
||
for line in lines do | ||
lineno = lineno + 1 | ||
var current = line.clone() | ||
current.strip() | ||
|
||
if current.size() == 0 then | ||
continue | ||
end | ||
|
||
try | ||
match current(0)? | ||
| ';' | '#' => | ||
// Skip comments. | ||
continue | ||
| '[' => | ||
try | ||
current.delete(current.find("]", 1)?, -1) | ||
current.delete(0) | ||
section = consume current | ||
if not f.add_section(section) then | ||
return ok | ||
end | ||
else | ||
ok = false | ||
|
||
if not f.errors(lineno, IniIncompleteSection) then | ||
return false | ||
end | ||
end | ||
else | ||
try | ||
let delim = try | ||
current.find("=")? | ||
else | ||
current.find(":")? | ||
end | ||
|
||
let value = current.substring(delim + 1) | ||
value.strip() | ||
|
||
current.delete(delim, -1) | ||
current.strip() | ||
|
||
try | ||
let comment = try | ||
value.find(";")? | ||
else | ||
value.find("#")? | ||
end | ||
|
||
match value(comment.usize() - 1)? | ||
| ' ' | '\t' => | ||
value.delete(comment, -1) | ||
value.rstrip() | ||
end | ||
end | ||
|
||
if not f(section, consume current, consume value) then | ||
return ok | ||
end | ||
else | ||
ok = false | ||
|
||
if not f.errors(lineno, IniNoDelimiter) then | ||
return false | ||
end | ||
end | ||
end | ||
end | ||
end | ||
ok |
Oops, something went wrong.