diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer/container.nim | 7 | ||||
-rw-r--r-- | src/config/config.nim | 19 | ||||
-rw-r--r-- | src/config/toml.nim | 57 | ||||
-rw-r--r-- | src/display/pager.nim | 15 |
4 files changed, 81 insertions, 17 deletions
diff --git a/src/buffer/container.nim b/src/buffer/container.nim index a148e0e1..a08f4cb0 100644 --- a/src/buffer/container.nim +++ b/src/buffer/container.nim @@ -97,8 +97,11 @@ type events*: Deque[ContainerEvent] startpos: Option[CursorPosition] hasstart: bool + redirectdepth*: int -proc newBuffer*(dispatcher: Dispatcher, config: Config, source: BufferSource, cookiejar: CookieJar, title = ""): Container = +proc newBuffer*(dispatcher: Dispatcher, config: Config, source: BufferSource, + cookiejar: CookieJar, title = "", + redirectdepth = 0): Container = let attrs = getWindowAttributes(stdout) let config = config.getBufferConfig(source.location, cookiejar) let ostream = dispatcher.forkserver.ostream @@ -112,7 +115,7 @@ proc newBuffer*(dispatcher: Dispatcher, config: Config, source: BufferSource, co result = Container( source: source, attrs: attrs, width: attrs.width, height: attrs.height - 1, contenttype: source.contenttype, - title: title, config: config + title: title, config: config, redirectdepth: redirectdepth ) istream.sread(result.process) result.pos.setx = -1 diff --git a/src/config/config.nim b/src/config/config.nim index 73072763..16e1c652 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -315,14 +315,17 @@ proc parseConfig(config: Config, dir: string, t: TomlValue) = assert conf.url.isSome != conf.host.isSome config.siteconf.add(conf) of "omnirule": - for v in v: - var rule = StaticOmniRule() - for k, v in v: - case k - of "match": rule.match = v.s - of "substitute-url": rule.subst = v.s - if rule.match != "": - config.omnirules.add(rule) + if v.vt == VALUE_ARRAY and v.a.len == 0: + config.omnirules.setLen(0) + else: + for v in v: + var rule = StaticOmniRule() + for k, v in v: + case k + of "match": rule.match = v.s + of "substitute": rule.subst = v.s + if rule.match != "": + config.omnirules.add(rule) proc parseConfig(config: Config, dir: string, stream: Stream) = config.parseConfig(dir, parseToml(stream)) diff --git a/src/config/toml.nim b/src/config/toml.nim index 2c4550b5..89277d24 100644 --- a/src/config/toml.nim +++ b/src/config/toml.nim @@ -323,7 +323,10 @@ proc consumeNoState(state: var TomlParser): bool = node.map[table.key[i]] = TomlValue(vt: VALUE_TABLE, t: t2) node = t2 if table.key[^1] in node.map: - let last = node.map[table.key[^1]] + var last = node.map[table.key[^1]] + if last.vt == VALUE_ARRAY and last.a.len == 0: + last = TomlValue(vt: VALUE_TABLE_ARRAY) + node.map[table.key[^1]] = last if last.vt != VALUE_TABLE_ARRAY: let key = table.key.join('.') state.valueError(fmt"re-definition of node {key} as table array (was {last.vt})") @@ -396,11 +399,59 @@ proc consumeArray(state: var TomlParser): TomlValue = of ',': if val == nil: state.syntaxError("comma without element") - result.a.add(val) + if val.vt == VALUE_TABLE: + # inline table array + result = TomlValue(vt: VALUE_TABLE_ARRAY) + result.ta.add(val.t) + else: + result.a.add(val) else: + if val != nil: + state.syntaxError("missing comma") state.reconsume() val = state.consumeValue() +proc consumeInlineTable(state: var TomlParser): TomlValue = + result = TomlValue(vt: VALUE_TABLE, t: TomlTable()) + var key: seq[string] + var haskey: bool + var val: TomlValue + while state.has(): + let c = state.consume() + case c + of ' ', '\t', '\n': discard + of '}': + if val != nil: + result.a.add(val) + break + of ',': + if key.len == 0: + state.syntaxError("missing key") + if val == nil: + state.syntaxError("comma without element") + var table = result.t + for i in 0 ..< key.high: + let k = key[i] + if k in table.map: + state.syntaxError(fmt"invalid re-definition of key {k}") + else: + let node = TomlTable() + table.map[k] = TomlValue(vt: VALUE_TABLE, t: node) + table = node + let k = key[^1] + if k in table.map: + state.syntaxError(fmt"invalid re-definition of key {k}") + table.map[k] = val + else: + if val != nil: + state.syntaxError("missing comma") + if not haskey: + key = state.consumeKey() + haskey = true + else: + state.reconsume() + val = state.consumeValue() + proc consumeValue(state: var TomlParser): TomlValue = while state.has(): let c = state.consume() @@ -417,6 +468,8 @@ proc consumeValue(state: var TomlParser): TomlValue = #TODO date-time of '[': return state.consumeArray() + of '{': + return state.consumeInlineTable() elif c.isBare(): let s = state.consumeBare(c) case s diff --git a/src/display/pager.nim b/src/display/pager.nim index 06b28346..66280edc 100644 --- a/src/display/pager.nim +++ b/src/display/pager.nim @@ -483,7 +483,9 @@ proc applySiteconf(pager: Pager, request: Request) = pager.cookiejars[request.url.host] = newCookieJar(request.url) # Load request in a new buffer. -proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none(string), replace: Container = nil) = +proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), + ctype = none(string), replace: Container = nil, + redirectdepth = 0) = pager.applySiteconf(request) if prevurl.isnone or not prevurl.get.equals(request.url, true) or request.url.hash == "" or request.httpmethod != HTTP_GET: @@ -500,7 +502,7 @@ proc gotoURL*(pager: Pager, request: Request, prevurl = none(URL), ctype = none( location: request.url ) let cookiejar = pager.cookiejars.getOrDefault(request.url.host) - let container = pager.dispatcher.newBuffer(pager.config, source, cookiejar) + let container = pager.dispatcher.newBuffer(pager.config, source, cookiejar, redirectdepth = redirectdepth) if replace != nil: container.replace = replace container.copyCursorPos(container.replace) @@ -711,9 +713,12 @@ proc handleEvent0(pager: Pager, container: Container, event: ContainerEvent): bo if pager.container == container: pager.authorize() of REDIRECT: - let redirect = event.location - pager.alert("Redirecting to " & $redirect) - pager.gotoURL(newRequest(redirect), some(pager.container.source.location), replace = pager.container) + if container.redirectdepth < 10: + let redirect = event.location + pager.alert("Redirecting to " & $redirect) + pager.gotoURL(newRequest(redirect), some(container.source.location), replace = container, redirectdepth = container.redirectdepth + 1) + else: + pager.alert("Error: maximum redirection depth reached") of ANCHOR: var url2 = newURL(container.source.location) url2.hash(event.anchor) |