10 KiB
BrmBuro
Brmlab Bureacratic system.
License
ISC License
Copyright 2023 Brmlab, z.s. Dominik Pantůček dominik.pantucek@trustica.cz
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Features
- members base management
- member files parsing and validation
- member ids validation
- generating new member id
- per-month statistics of active, suspended, destroyed and student members
- detailed member information
- querying members by id or nick
Requirements
There are no runtime requirements, it is possible to build binary that requires only libc.
Build requirements:
- Chicken Scheme 5
- make (tested with GNU make)
Building static binary:
make brmsaptool-static
It is possible to run the main tool as script with Chicken Scheme interpreter and POSIX-compatible shell for the purpose of development.
Development requirements:
- POSIX shell
Functional Modules
Configuration
Member File
Member Record
Member Base
Month
Period
Primes
Support Modules
There modules are not specific to this project but had to be implemented anyway to not require any external dependencies.
ANSI
Command Line parsing
Dictionary
Simple key/value dictionary with most operations implemented in linear
time. The dictionary is internally represented as assq
list and
is best suitable for symbols and numbers as keys.
(make-dict)
Creates an empty dictionary.
(dict-has-key? d k)
d
- the dictionaryk
- key to check
Returns #t
(true) if the dictionary d
contains the key
k
.
(dict-ref d k [v])
d
- the dictionaryk
- the key to retrievev
- optional default value
Retrieves given key k
from the dictionary d
.
If the key is not stored in the dictionary an error is raised unless
an optional value v
is provided which is then returned in that
case.
(dict-remove d k)
d
- the dictionaryk
- the key to remove
Removes the key k
from the given dictionary d
raising an
exception if the key is not stored in the dictionary.
(dict-set d k v)
d
- the dictionaryk
- key to (re)setv
- the value to set
If the dictionary d
does not contain the key k
, adds the
value v
into it under the given key. If the key is present, its
value is then replaced.
(dict-keys d)
d
- the dictionary
Returns the list of keys contained in the dictionary d
.
(dict-map proc d)
proc
- procedure for processingd
- the dictionary
Returns a dictionary created by processing all elements of the
dictionary d
using the procedure proc
.
If the procedure accepts just one argument, only values are passed to it. If the procedure accepts two arguments, both the key and value are passed to it. In both cases, the procedure must produce only the value.
(dict-filter pred? d)
pred?
- predicate procedured
- the dictionary
Returns a new dictionary created by keeping only the key/value pairs
from the dictionary d
matching the predicate pred?
.
If the procedure accepts just one argument, only values are passed to it. If the procedure accepts two arguments, both the key and value are passed to it.
(dict-reduce init proc d)
init
- arbitrary initial valueproc
- procedure for performing the reducing stepd
- the dictionary to reduce
Iterates over the key/value pairs of given dictionary d
initializing the algorithm with the init
value given. In each
step the procedure proc
is called with three arguments: the
value accumulated so far, key and value.
Listing
This module implements listing a text file with line numbers and optional highlights of given source lines, optionally with comments for those lines.
(print-source-listing lines highlights context hl-pre hl-post ctx-pre ctx-post ellipsis)
lines
- list of string representing lines of the text filehighlights
- list of highlights (see below)context
- number of context lines to be shown around highlighted lieshl-pre
- string introducing highlighted lineshl-post
- string terminating highlighted linesctx-pre
- string introducing context linesctx-post
- string terminating context linesellipsis
- string representing lines omitted from the output
Prints given text file represented by the lines
list of strings.
Lines to be highlighted can be specified in the highlights
list. The highlight specification is either a number or a list
containing the line number and string comment.
The lines are actually highlighted by prepending them with
hl-pre
string and the highlight is finished by appending
hl-post
to them. Usually some constants from the ansi
module are used.
If some lines are highlighted a number of context
lines
surrounding them may be printed as well. If this argument is negative,
all non-highlighted lines are printed as context lines.
Context lines are prepended with ctx-pre
string and terminated
by ctx-post
string.
If some lines between highlight and/or context lines are omitted,
ellipsis
string is printed on single line as a substitute.
Progress
Provides syntax forms and procedures for showing progress of a process.
(with-progress echo? pre post body ...)
echo?
- flag enabling progress outputpre
- string to be printed at startpost
- string to be printed after finishbody ...
- expressions of the process tracked
Displays process progress starting with the pre
string, adding
arbitrary string to the output using the progress-advance
during
each and every step. If the process reaches its finish, the output
line is finished with the post
string and cursor is moved to new
line.
During the steps, the whole line is always refreshed when the progress gets updated.
If echo?
is #f
(false), nothing is output.
(progress-advance [str])
str
- string to add to progress, defaults to "."
Adds given string to current progress and refreshes the progress
line. Must be evaluated within with-progress
expression.
(progress-break body ...)
body ...
- arbitrary expressions to be evaluated
Evaluates the body ...
expressions. Hides current progress line
before the evaluation and redisplays it when finished.
Testing
This module provides simple syntax forms for (unit) testing of other modules.
(run-tests name body ...)
name
- identifier describing the module being testedbody ...
- test expressions
Runs all tests specified on the body ...
. Firstly it prints
"[test] name " at the beginning of the line. Secondly it runs all
tests, printing "." for each test successfully passed. If all tests
pass, prints " ok." and moves the cursor to the next line.
In case any of the tests fails, exception is raised and program terminates.
(test-eq? name expression expected-result)
name
- identifier representing the name of the testexpression
- expression to be evaluatedexpected-result
- expected result of the test expression
Evaluates the test expression
and compares the result with
expected-result
using eq?
. If the comparison fails, an
exception is raised with the name
of the test added to the
exception. If the test passes, prints "." like all tests from this
module do.
(test-equal? name expression expected-result)
name
- identifier representing the name of the testexpression
- expression to be evaluatedexpected-result
- expected result of the test expression
Evaluates the test expression
and compares the result with
expected-result
using equal?
. If the comparison fails, an
exception is raised with the name
of the test added to the
exception. If the test passes, prints "." like all tests from this
module do.
(test-true name expression)
name
- identifier representing the name of the testexpression
- expression to be evaluated
Evaluates the test expression
and checks whether the result is
#t
(true). An exception is raised if it is not with the
name
of the test added to the exception. If the test passes,
prints "." like all tests from this module do.
(test-false name expression)
name
- identifier representing the name of the testexpression
- expression to be evaluated
Evaluates the test expression
and checks whether the result is
#f
(false). An exception is raised if it is not with the
name
of the test added to the exception. If the test passes,
prints "." like all tests from this module do.
(test-exn name expression)
name
- identifier representing the name of the testexpression
- expression to be evaluated
Evaluates the test expression
and checks whether it raised an
exception. An exception is raised if no exception was raised during
the evaluation. If the test passes, prints "." like all tests from
this module do.
Utils
To ensure there are no external dependencies (including chicken eggs), this module re-implements any basic procedures which are required for any algorithms used.
(filter pred? lst)
pred?
- procedure accepting any value and returning #t or #flst
- list to be filtered
Returns a list containing only elements matching given pred?
predicate.