# A doubly linked list permits bidirectional traversal. container duplex-list:_elem [ value:_elem next:&:duplex-list:_elem prev:&:duplex-list:_elem ] def push x:_elem, in:&:duplex-list:_elem/contained-in:result -> result:&:duplex-list:_elem [ local-scope load-inputs result:&:duplex-list:_elem <- new {(duplex-list _elem): type} *result <- merge x, in, null return-unless in put *in, prev:offset, result ] def first in:&:duplex-list:_elem -> result:_elem [ local-scope load-inputs { break-if in zero:&:_elem <- new _elem:type zero-result:_elem <- copy *zero abandon zero return zero-result } result <- get *in, value:offset ] def next in:&:duplex-list:_elem -> result:&:duplex-list:_elem/contained-in:in [ local-scope load-inputs return-unless in, null result <- get *in, next:offset ] def prev in:&:duplex-list:_elem -> result:&:duplex-list:_elem/contained-in:in [ local-scope load-inputs return-unless in, null result <- get *in, prev:offset return result ] scenario duplex-list-handling [ run [ local-scope # reserve locations 0-9 to check for missing null check 10:num/raw <- copy 34 11:num/raw <- copy 35 list:&:duplex-list:num <- push 3, null list <- push 4, list list <- push 5, list list2:&:duplex-list:num <- copy list 20:num/raw <- first list2 list2 <- next list2 21:num/raw <- first list2 list2 <- next list2 22:num/raw <- first list2 30:&:duplex-list:num/raw <- next list2 31:num/raw <- first 30:&:duplex-list:num/raw 32:&:duplex-list:num/raw <- next 30:&:duplex-list:num/raw 33:&:duplex-list:num/raw <- prev 30:&:duplex-list:num/raw list2 <- prev list2 40:num/raw <- first list2 list2 <- prev list2 41:num/raw <- first list2 50:bool/raw <- equal list, list2 ] memory-should-contain [ 0 <- 0 # no modifications to null pointers 10 <- 34 11 <- 35 20 <- 5 # scanning next 21 <- 4 22 <- 3 30 <- 0 # null 31 <- 0 # first of null 32 <- 0 # next of null 33 <- 0 # prev of null 40 <- 4 # then start scanning prev 41 <- 5 50 <- 1 # list back at start ] ] def length l:&:duplex-list:_elem -> result:num [ local-scope load-inputs result <- copy 0 { break-unless l result <- add result, 1 l <- next l loop } ] # insert 'x' after 'in' def insert x:_elem, in:&:duplex-list:_elem -> in:&:duplex-list:_elem [ local-scope load-inputs new-node:&:duplex-list:_elem <- new {(duplex-list _elem): type} *new-node <- put *new-node, value:offset, x # save old next before changing it next-node:&:duplex-list:_elem <- get *in, next:offset *in <- put *in, next:offset, new-node *new-node <- put *new-node, prev:offset, in *new-node <- put *new-node, next:offset, next-node return-unless next-node *next-node <- put *next-node, prev:offset, new-node ] scenario inserting-into-duplex-list [ local-scope list:&:duplex-list:num <- push 3, null list <- push 4, list list <- push 5, list run [ list2:&:duplex-list:num <- next list # inside list list2 <- insert 6, list2 # check structure like before list2 <- copy list 10:num/raw <- first list2 list2 <- next list2 11:num/raw <- first list2 list2 <- next list2 12:num/raw <- first list2 list2 <- next list2 13:num/raw <- first list2 list2 <- prev list2 20:num/raw <- first list2 list2 <- prev list2 21:num/raw <- first list2 list2 <- prev list2 22:num/raw <- first list2 30:bool/raw <- equal list, list2 ] memory-should-contain [ 10 <- 5 # scanning next 11 <- 4 12 <- 6 # inserted element 13 <- 3 20 <- 6 # then prev 21 <- 4 22 <- 5 30 <- 1 # list back at start ] ] scenario inserting-at-end-of-duplex-list [ local-scope list:&:duplex-list:num <- push 3, null list <- push 4, list list <- push 5, list run [ list2:&:duplex-list:num <- next list # inside list list2 <- next list2 # now at end of list list2 <- insert 6, list2 # check structure like before list2 <- copy list 10:num/raw <- first list2 list2 <- next list2 11:num/raw <- first list2 list2 <- next list2 12:num/raw <- first list2 list2 <- next list2 13:num/raw <- first list2 list2 <- prev list2 20:num/raw <- first list2 list2 <- prev list2 21:num/raw <- first list2 list2 <- prev list2 22:num/raw <- first list2 30:bool/raw <- equal list, list2 ] memory-should-contain [ 10 <- 5 # scanning next 11 <- 4 12 <- 3 13 <- 6 # inserted element 20 <- 3 # then prev 21 <- 4 22 <- 5 30 <- 1 # list back at start ] ] scenario inserting-after-start-of-duplex-list [ local-scope list:&:duplex-list:num <- push 3, null list <- push 4, list list <- push 5, list run [ list <- insert 6, list # check structure lik
#!/usr/bin/python

from __future__ import (absolute_import, division, print_function)

import os.path
import re
import sys


# Add relevant ranger module to PATH... there surely is a better way to do this...
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))


def report(boolean, errormessage):
    if not boolean:
        sys.stderr.write('TEST FAILURE: ')
        sys.stderr.write(errormessage)
        sys.stderr.write('\n')
        sys.stderr.flush()


def get_path_of_man_page():
    dirpath_of_this_file = os.path.dirname(__file__)
    return os.path.join(dirpath_of_this_file, '..', 'doc', 'ranger.pod')


def read_manpage():
    path = get_path_of_man_page()
    return open(path, 'r').read()


def get_sections():
    manpage = read_manpage()
    parts = manpage.split('=head1 ')
    sections = dict()
    for part in parts:
        if '\n' in part:
            section_name, section_content = part.split('\n', 1)
            sections[section_name] = section_content
        else:
            pass
    return sections


def find_undocumented_settings():
    from ranger.container.settings import ALLOWED_SETTINGS
    sections = get_sections()
    setting_section = sections['SETTINGS']
    matcher_pattern = r'^=item [\w\d_, ]*{setting}'
    for setting in ALLOWED_SETTINGS:
        matcher = re.compile(matcher_pattern.format(setting=setting), re.M)
        report(matcher.search(setting_section),
               ('Setting %s is not documented in the man page!' % setting))


if __name__ == '__main__':
    find_undocumented_settings()
t:], list ] trace-should-contain [ app: list: 3 <-> 2 <-> 1 ] ] def to-text in:&:duplex-list:_elem -> result:text [ local-scope load-inputs buf:&:buffer:char <- new-buffer 80 buf <- to-buffer in, buf result <- buffer-to-array buf ] # variant of 'to-text' which stops printing after a few elements (and so is robust to cycles) def to-text-line in:&:duplex-list:_elem -> result:text [ local-scope load-inputs buf:&:buffer:char <- new-buffer 80 buf <- to-buffer in, buf, 6 # max elements to display result <- buffer-to-array buf ] def to-buffer in:&:duplex-list:_elem, buf:&:buffer:char -> buf:&:buffer:char [ local-scope load-inputs { break-if in buf <- append buf, [[]] return } # append in.value to buf val:_elem <- get *in, value:offset buf <- append buf, val # now prepare next next:&:duplex-list:_elem <- next in nextn:num <- deaddress next return-unless next buf <- append buf, [ <-> ] # and recurse remaining:num, optional-input-found?:bool <- next-input { break-if optional-input-found? # unlimited recursion buf <- to-buffer next, buf return } { break-unless remaining # limited recursion remaining <- subtract remaining, 1 buf <- to-buffer next, buf, remaining return } # past recursion depth; insert ellipses and stop append buf, [...] ] scenario stash-empty-duplex-list [ local-scope x:&:duplex-list:num <- copy null run [ stash x ] trace-should-contain [ app: [] ] ]