# 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()