Compare commits

...

No commits in common. "deploy-base" and "master" have entirely different histories.

23 changed files with 1006 additions and 1 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*~

13
.travis.yml Normal file
View File

@ -0,0 +1,13 @@
language: c
sudo: false
# TODO: don't overwrite artifacts.
script:
- make
- ./travis/auto-push.sh "https://github.com/jsmaniac/os-test-framework.git" \
"git@github.com:jsmaniac/os-deploy-artifacts.git" \
"artifacts-$TRAVIS_BRANCH" \
"deploy-base" \
"82336783091193a09541c42d0f688c6478323952" \
"_build/artifacts" \
"$(if test "$TRAVIS_BRANCH" = "master"; then echo master; else echo dev; fi)"

116
LICENSE.txt Normal file
View File

@ -0,0 +1,116 @@
CC0 1.0 Universal
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.
For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>

17
Makefile Normal file
View File

@ -0,0 +1,17 @@
all: deps.svg deps.png deps.pdf
deps.dot: deps.sh
sh $< > $@
deps.svg: deps.dot Makefile
dot -Tsvg $< > $@
deps.png: deps.dot Makefile
dot -Tpng $< > $@
deps.ps: deps.dot Makefile
dot -Tpng $< > $@
deps.pdf: deps.ps Makefile
ps2pdf $< $@

View File

@ -1 +1,3 @@
Built artifacts for Composable {{{project-name}}} is currently under development.
It aims to become a multi-platform document-oriented operating system.

9
bootstappable/README.md Normal file
View File

@ -0,0 +1,9 @@
# A human-readable archive format, prefixed with a tiny binary stub which compiles the rest of the archive
This can be used as a self-contained means to distribute buildable source code
This can be used to audit the entirety of the source code, and check that building it produces the expected binary.
## Related work:
* bootstrappable.org

7
build-system/README.md Normal file
View File

@ -0,0 +1,7 @@
Simple build system.
* Purely functional, with reproducible and bootstrappable builds in mind
* Runs commands in isolated environments (virtual machine or `chroot` or `proot` with `env -i`)
* Inputs are distinguished at the syntactic level, and dependencies are automatically computed
* Does not rely on filesystem timestamps
* Results are memoized (if an output happens to be the same after regeneration, it will not be seen as an updated dependency)

96
build-system/mek.md Normal file
View File

@ -0,0 +1,96 @@
Ma proposition pour un `mek` bien, dites-moi vos opinions sur l'interface. Celle-ci passe autant que possible par le système de fichiers, parce qu'un `mek` bien sait parler aux files.
Problems solved:
* Forgotten dependencies: build in isolated environment
* Reactive builds (auto-rebuild): mek watch
* Access to the build environment: eval $(mek)
* What changed since last good build(s) without doing git commit all the time: mek source --good (also: cd toto.err.source/)
* Track downloads of third-party components: build in isolated environment without network access
* Archive of source and all dependencies, including downloaded stuff
Usage:
```
mek build toto # builds toto or toto.err in case of an error.
# Cached errors are displayed early, but the build is retried in case it was a cosmic ray.
mek clean # only necessary if a hardware or system failure (e.g. out of memory) made a build appear as SUCCESSFUL when it was not
# (e.g. a poorly-written test that expected an error, caught an OOM but the real execution would not have produced an error)
mek watch # rebuilds everything incrementally as soon as sources are modified (threads 1 and 3 or 2 and 3, see below).
mek daemon # same but with '&' after initialization
mek watch toto # rebuilds toto incrementally as soon as one of its transitive dependencies is modified
ls # show progress next to (future) targets and a symlink to the backup of their source
ls _build.err # stderr of the last build (if non-empty)
ls _build/err # stderr of the last build
ls _build/source/ # source of the last build
ls _build/good.source/ # source of the last successful build
ls _build/err.source/ # source of the last failed build
ls toto.err # stderr when building toto (if non-empty)
ls toto.source # source of the last build of toto
ls toto.good.source # source of the last successful build of toto
ls toto.err.source # source of the last failed build of toto
mek source # dumps the source of the last build
mek source --good # dumps the source of the last successful build
mek source --err # dumps the source of the last failed build
mek source toto # dumps the source of the last successful build of toto
mek source toto.err # dumps the source of the last failed build of toto
eval $(mek) # builds and adds the output bin directory to $PATH etc.
eval "$(mek)" # same
$(mek) # same
. mekfile.sh # same
mek; copy-paste output # same
$(mek daemon) # same but detaches right away and builds incrementally in the background
eval $(mek build toto) # adds an output bin directory containing only toto (can be a collection of outputs) to $PATH etc.
mek shell toto # subshell in the directory and with the env of the recipe that builds toto
mek shell toto.err # same as above
eval $(mek shell toto) # cd to build directory for toto and add to $PATH etc.
mek archive toto # toto.tar now contains the source of toto and of all its dependencies with a build.sh
```
Example session:
```
$ $(mek daemon)
$ ls
(toto 60%) toto.source toto.c toto.h
$ ls
toto toto.source toto.c toto.h
$ echo "bad stuff" >> toto.h
$ ls
toto (34%) toto.c toto.h
$ ls
toto toto.source toto.err toto.err.source toto.c toto.h
$ meld $(mek source --good) $(mek source)
$ echo "fix bug" >> toto.h
$ ls
toto toto.source toto.c toto.h
```
In a `mekfile`:
```
toto: toto.h
# automatic dependency on the gcc executable and on toto.c
# "," is the unquote from scheme, it escapes from the implicitly-quoted shell command.
# Maybe gcc (a variable pointing to a third-party tool) should be distinguished from toto.c (a local file)
> ,gcc ,toto.c -o ,output
```
* Uses hashes, not timestamps
* Builds are done in isolated environments (cd, proot, Nix, chroot, container, VM, whatever is available), which only contain the dependencies.
* Transitions are atomic (mv of a symlink), so that the bin folder in the $PATH contains executables from the same version of the source, not toto from one version and tata from another.
* Two builds can run in parallel without interfering with each other, yet if work can be shared it will be.
Note about build threads:
* Invariant when threads 2 and 3 are enabled: if the user constantly modifies a file, e.g. `while sleep 1; do date > somesource; done` which produces an infinite stream of changes, and one of the versions causes the compiler to deadlock / go in an infinite loop, `mek` will still eventually produce an infinite stream of output binaries, where the latest produced binary is not based on a "very old" change (i.e. it is not a queue of jobs that grows indefinitely). It tries to build the latest changes, but it is resistant to the compiler hanging forever on some inputs, and it is resistant to a rapid stream of changes that could cause a naive algorithm to always restart without ever finishing any build.
* Thread 1 builds, and then checks for new changes. (If the build gets stuck in an infinite loop or deadlocks, the build never finishes and new changes are never taken into account.)
* Thread 2 builds, but aborts and restarts as soon as there's any change. Upon completion it kills threads 1 and 3 because it got a successful build of a more recent version. (If you're constantly modifying and the build takes a while, it never gets a chance to finish.)
* Thread 3 works like thread 1 but aborts if there are new changes and the build took longer than a timeout, e.g. twice the time of the last successful build by any thread and increasing geometrically
Random requirements:
* meta-rules: a rule which returns rules. Can be memoized easily, and be part of the normal reactive flow.
* Easy changes of config: dev / build, -O3, -Odebug etc.

1
chameleon/README.md Normal file
View File

@ -0,0 +1 @@
Build rules to generate different file types. The rules for more than one file type can be applied, as long as the resulting bytes generated by each rule are the same for the same offsets.

289
deps.sh Executable file
View File

@ -0,0 +1,289 @@
#!/bin/sh
# align on "->" and "[" keyboard macro:
# (fset 'indent->\[ [C-home ?\C-s ?. ?d ?i ?g ?r ?a ?p ?h ?\C-m home ?\C- ?\C-s ?. ?\} ?\C-m ?\M-x ?a ?l ?i ?g ?n ?- ?r ?e ?g ?e ?x ?p ?\C-m ?- ?> ?\C-m C-home ?\C-m ?\C-? ?\C-s ?. ?d ?i ?g ?r ?a ?p ?h ?\C-m home ?\C- ?\C-s ?. ?\} ?\C-m ?\M-x ?a ?l ?i ?g ?n ?- ?r ?e ?g ?e ?x ?p ?\C-m ?\[ ?\[ ?\] ?\C-m ?\C-m ?\C-?])
(sed -e '/^\./!s/^\( *\)\([^ "][^ ]*\)/\1"\2"/' \
|sed -e '/^\./!s/^\( *\([^-]\|-[^>]\)\+ *-> *\)\([^ "][^ ]*\)/\1"\3"/' \
|sed -e '/^\./!s/3rdpartybin/shape=box/' \
|sed -e '/^\./!s/3rdpartyplatform/shape=box/' \
|sed -e '/^\./!s/bdep/style=dashed/' \
|sed -e '/^\./!s/rdep/style=solid/' \
|sed -e '/^\./!s/\([[].*\)mostly-solved/\1fillcolor=yellow,style=filled/' \
|sed -e '/^\./!s/\([[].*\)unsolved+problem/\1fillcolor=red,style=filled/' \
|sed -e '/^\./!s/\([[].*\)many-to-do-ok/\1fillcolor=azure,style=filled/' \
|sed -e '/^\./!s/\([[].*\)many-to-do/\1fillcolor=deepskyblue,style=filled/' \
|sed -e '/^\./!s/\([[].*\)unsolved/\1fillcolor=orange,style=filled/' \
|sed -e '/^\./!s/\([[].*\)solved/\1fillcolor=darkolivegreen1,style=filled/' \
|sed -e '/^\./!s/\([[].*\)implemented/\1fillcolor=green,style=filled/' \
|sed -e '/^\./!s/\([[].*\)currentwip/\1color=green,penwidth=5/' \
|sed -e '/^\./!s/\([[].*\)wip/\1color=green,penwidth=5,style="filled,dashed"/' \
|sed -e 's/^\./ /') <<'EOF'
.digraph g {
. compound=true
. subgraph cluster_legend {
. label=legend
. subgraph cluster_legend_deps {
. label="dependencies"
"third-party tool" [3rdpartybin]
component -> build-dep [bdep]
component -> run-time-dep [rdep]
. }
. subgraph cluster_legend_solved {
. label="solved (theoretically)"
.// subgraph cluster_legend_solved_ok {
.// style=invis label="";
implemented [implemented]
solved [solved]
many-to-do-ok [many-to-do-ok,label="many to implement\nsimpler workaround"]
.// }
.// subgraph cluster_legend_solved_problem {
.// style=invis label="";
"mostly solved" [mostly-solved]
unsolved [unsolved]
many-to-do [many-to-do, label="many to implement\n500-page standards\npoorly explained\npoorly indexed"]
"open problem?" [unsolved+problem]
.// }
. }
. subgraph cluster_legend_implem {
. label="implementation"
wip [wip,fillcolor=none]
"current wip" [currentwip]
. }
. }
. subgraph cluster_host_platform {
. label="host platform"
host-platform [3rdpartyplatform,label="host = one of …"]
sh [3rdpartyplatform]
x86-bootsector [3rdpartyplatform]
raspberry-pi [3rdpartyplatform]
windows-.exe [3rdpartyplatform]
html+js [3rdpartyplatform]
host-platform-more [3rdpartyplatform,label="…"]
. }
host-platform -> sh [rdep]
host-platform -> x86-bootsector [rdep]
host-platform -> raspberry-pi [rdep]
host-platform -> windows-.exe [rdep]
host-platform -> html+js [rdep]
host-platform -> host-platform-more [rdep]
. subgraph cluster_build_os {
. label="bootstrap build of the OS"
nano-scheme [solved,currentwip]
micro-scheme [solved]
reproducible-environment [solved]
chameleon [solved,wip]
build-system [mostly-solved]
bootstrappable [solved]
gcc [3rdpartybin]
sgdisk [3rdpartybin]
zip [3rdpartybin]
other-chameleon-tools [3rdpartybin,label="other tools"]
micro-scheme -> nano-scheme [rdep]
build-system -> micro-scheme [rdep]
Guix -> "Guix bootstrap" [bdep]
Nix -> Guix [bdep]
build-system -> bootstrappable [rdep]
build-system -> reproducible-environment [rdep]
chameleon -> build-system [rdep]
chameleon -> gcc [rdep]
chameleon -> sgdisk [rdep]
chameleon -> zip [rdep]
chameleon -> other-chameleon-tools [rdep]
proot [3rdpartybin]
run-in-emulator [solved,wip]
. subgraph cluster_tests {
. label="tests"
tests/portability [label=portability]
tests/gui [label=gui]
tests/bootstrappable-builds [label="build is\nbootstrappable"]
subimage-search [implemented]
tests/reproducible-builds [label="build is\nreproducible"]
. }
qemu [3rdpartybin]
. subgraph cluster_repro_env {
. label="reproducible build environment (software, hardware)"
reproducible-environment
Nix
proot
"POSIX system" [3rdpartyplatform]
. }
. }
. subgraph cluster_programming_language {
. label="programming language"
programming-language
typesystem [mostly-solved]
syntax [solved]
semantics [mostly-solved]
vm [unsolved]
IDE [solved]
refactoring [mostly-solved]
hyper-literate [solved]
"package management\n(deps & versions)" [unsolved+problem]
. }
. subgraph cluster_portble_platform {
. label="portable platform"
"portable execution stubs"
basic-drivers [solved]
"more drivers\n(udi,hypervised linux)" [many-to-do-ok]
. }
vm -> "portable execution stubs" [rdep]
"portable execution stubs" -> chameleon [bdep]
"portable execution stubs" [solved]
run-in-emulator
. subgraph cluster_gui {
. label="gui"
gui [mostly-solved]
constraint-solver [mostly-solved]
graph-layout [unsolved]
constraint-solver-contract [unsolved+problem]
relative-arbitrary-precision [mostly-solved]
zoomable [mostly-solved]
. }
. subgraph cluster_document_model {
. label="document model"
"general\nprinciples" [solved]
. subgraph cluster_viewers {
. label="viewers"
"rich text lens" [solved]
"list lens" [solved, label="column-list lens"]
"set lens" [solved]
"compound document lens" [solved]
. }
. subgraph cluster_tools {
. label="tools"
sort [solved]
filter [solved]
project [solved]
other-tools [mostly-solved,label="…"]
. }
. subgraph cluster_algorithms {
. label="algorithms"
other-algorithms [label="…",many-to-do]
"abstract datatypes" [solved]
union-find [solved]
"sat solver" [solved]
raytracing [solved]
sort-algo [label="sort",solved]
. }
. subgraph cluster_documents {
. label="data / document types"
transformation-of [solved]
styled-layout-of [solved]
printable-layout [unsolved]
compound-document [solved]
. subgraph cluster_simple_data {
. label="simple data"
"vectorial image" [unsolved]
"bitmap image" [solved]
set [solved]
list [solved,label="list / database"]
"rich text" [solved]
. }
. }
. subgraph cluster_data_sources {
. label="data sources"
. subgraph cluster_importers {
. label="importers"
"word" [many-to-do]
"excel" [many-to-do]
"PDF" [many-to-do]
"RTF" [many-to-do]
"PSD" [many-to-do]
"SVG" [many-to-do]
. }
. subgraph cluster_network {
. label="network and protocols"
"websites\n(webkit in sandbox)" [many-to-do-ok]
more-network-protocols [many-to-do, label="…"]
"NTP" [solved]
"REST APIs" [many-to-do]
. }
. }
. }
"REST APIs" -> compound-document [ltail=cluster_data_sources,lhead=cluster_documents]
compound-document -> styled-layout-of
compound-document -> transformation-of
compound-document -> list [lhead=cluster_simple_data]
styled-layout-of -> printable-layout
"list lens" -> compound-document [ltail=cluster_viewers,lhead=cluster_documents]
. /*
"list lens" -> list
"set lens" -> set
"compound document lens" -> "compound document"
"rich text lens" -> "rich text"
. */
"set lens" -> gui [rdep,ltail=cluster_viewers]
. /*
"set lens" -> gui
"compound document lens" -> gui
"rich text lens" -> gui
. */
"compound document lens" -> constraint-solver
"compound document lens" -> graph-layout
sort -> sort-algo [rdep,ltail=cluster_tools,lhead=cluster_algorithms]
other-algorithms -> "abstract datatypes" [rdep]
union-find -> "abstract datatypes" [rdep]
"sat solver" -> "abstract datatypes" [rdep]
raytracing -> "abstract datatypes" [rdep]
sort-algo -> "abstract datatypes" [rdep]
sort -> compound-document [rdep,ltail=cluster_tools,lhead=cluster_documents]
list -> typesystem [bdep,ltail=cluster_documents]
. /*
sort -> list
filter -> list
project -> list
. */
reproducible-environment -> Nix
reproducible-environment -> proot
reproducible-environment -> run-in-emulator
reproducible-environment -> "POSIX system"
tests/portability -> subimage-search [rdep]
tests/gui -> subimage-search [rdep]
tests/portability -> run-in-emulator [rdep]
nano-scheme -> sh [rdep]
gui -> basic-drivers [rdep]
Guix [3rdpartybin]
"Guix bootstrap" [3rdpartybin]
Nix [3rdpartybin]
basic-drivers -> host-platform [rdep]
gui -> programming-language [bdep]
programming-language -> typesystem [rdep]
programming-language -> vm [rdep]
run-in-emulator -> qemu [rdep]
subimage-search
tests/reproducible-builds
"portable execution stubs" -> "host-platform" [rdep]
SVG -> "REST APIs" [style=invis]
many-to-do-ok -> "current wip" [style=invis]
printable-layout -> "zoomable" [style=invis]
_sh [style=invis]
_sh -> "sh" [style=invis]
"current wip" -> "general\nprinciples" [style=invis]
"Guix bootstrap" -> _sh [style=invis]
styled-layout-of -> set [style=invis]
"general\nprinciples" -> "list lens" [style=invis]
.}
EOF
#dynalist → c'est une mind map (moche) avec des checkbox, dates et hashtags?
# mode lecture 1 focus, édition 1 focus, édition+référence: 2 focus, édition+référence+outils: 3 focus, édition+référence+calculs+style+outils: 5 focus
# DK encyclo vs. Android encyclopedias
# DK book on multimedia
# keyboard
# hw difficulties:
# * PCB layout: lots of interferences (see rowhammer…)
# * GPU is one of the most opaque components. In the Raspberry Pi it means that the boot process is partially opaque.
# * Stateless : a lot of components have flashable firmware nowadays
# * Opaque / undocumented HW
# * casing (high precision otherwise buttons get stuck or jiggle)
# * If you want to make your own hardware, probably best is to hire someone who did it for a small-scale project (e.g. EvilDragon who did the Pandora and Pyra)

3
drivers/README.md Normal file
View File

@ -0,0 +1,3 @@
Drivers to access features of the host.
This includes pipes, network, sound and GUI access when running as a process, screen, SD card and keyboard when running as a Raspberry Pi Operating System.

21
fork.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
if test $# -ne 1 || test "$1" = '-h' || test "$1" = '--help'; then
echo 'Usage: ./fork.sh name'
echo 'Renames the project'
exit 1
fi
if printf %s "$1" | grep -q -v '[-0-9a-zA-Z_ ]'; then
echo 'The name should not contain characters outside of [-0-9a-zA-Z_ ]'
echo 'TODO: escape problematic characters in the regexp and allow them'
exit 1
fi
if git grep -q -e "$1"; then
echo "The proposed name already appears in the source code."
echo "If you proceed, the new name will prevent easy renaming of this code base."
exit 1
fi
git ls-tree -r HEAD | awk '{ print $4 }' | xargs sed -i -e 's/{{{project-name}}}/'"$1"/g

3
gui/README.md Normal file
View File

@ -0,0 +1,3 @@
Layout engine
Zoomable user interface

1
micro-scheme/README.md Normal file
View File

@ -0,0 +1 @@
# A tiny scheme implemented in POSIX SH

181
micro-scheme/micro-scheme.sh Executable file
View File

@ -0,0 +1,181 @@
#!/bin/sh
heap_init() {
heap_max=0
}
alloc_cons_ptr_ptr_unit() {
# args: $1 must be an heap pointer (non-negative integer)
# $2 must be an heap pointer (non-negative integer)
# input: heap_max
# output: heap_max++ heap_type_$heap_max heap_car_$heap_max heap_cdr_$heap_max
# clobbers: none
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
# heap_max++
heap_max=$((heap_max+1))
# heap_type[heap_max] = C
eval heap_type_$heap_max=C
# heap_car[heap_max] = $1
eval heap_car_$heap_max='"'$1'"'
# heap_cdr[heap_max] = $2
eval heap_cdr_$heap_max='"'$2'"'
}
alloc_primitive_hex_unit() {
# args: $1 must be a hexadecimal string
# input: heap_max
# output: heap_max++ heap_type_$heap_max heap_value_$heap_max
# clobbers: none
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
# heap_max++
heap_max=$((heap_max+1))
# heap_type[heap_max] = P
eval heap_type_$heap_max=P
# heap_value[heap_max] = $1
eval heap_value_$heap_max='"'$1'"'
}
car() {
eval 'printf %s "$heap_car_'$1'"'
}
cdr() {
eval 'printf %s "$heap_cdr_'$1'"'
}
value() {
eval 'printf %s "$heap_value_'$1'"'
}
debug_print() {
eval 'tmpdebug=$heap_type_'"$1"
if test $tmpdebug = C; then
printf '('
eval 'tmpdebugb=$heap_car_'$1
(debug_print $tmpdebugb)
printf ' . '
eval 'tmpdebugb=$heap_cdr_'$1
(debug_print $tmpdebugb)
printf ')'
else
eval 'printf "[%s]" "$heap_value_'$1'"'
fi
}
stack_init_name_unit() {
eval "stacklast_${1}=0"
}
stack_push_name_hex_unit() {
# args: $1 must be an [a-z]+ name
# $2 must be a hexadecimal string
# input: stacklast_$1
# output: stacklast_$1 stack_$1_${!stacklast_$1+1}
# clobbers: stacklast
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
eval stacklast='${'stacklast_${1}'}'
stacklast=$((${stacklast}+1))
echo stack_${1}_${stacklast}='"'${2}'"'
eval stack_${1}_${stacklast}='"'${2}'"'
eval stacklast_${1}=${stacklast}
}
stack_len_name_int() {
# args: $1 must be an [a-z]+ name
# input: stacklast_$1
# output: stdout=${!stacklast_$1}
# clobbers: nothing
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
eval 'printf %s ${'stacklast_${1}'}'
}
stack_pop_name_result_unit() {
# args: $1 must be an [a-z]+ name
# input: stacklast_$1
# output: stacklast_$1 stack_$1_${!stacklast_$1}
# clobbers: stacklast
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
eval stacklast='${'stacklast_${1}'}'
eval $2'="${'stack_${1}_${stacklast}'}"'
stacklast=$((${stacklast}-1))
eval stacklast_${1}=${stacklast}
}
stack_peek_name_hex() {
# args: $1 must be an [a-z]+ name
# input: stacklast_$1 stack_$1_${!stacklast_$1}
# output: stdout
# clobbers: stacklast
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
eval stacklast='${'stacklast_${1}'}'
eval 'printf %s "${'stack_${1}_${stacklast}'}"'
}
stack_init_name_unit parse_stack
stack_push_name_hex_unit parse ''
heap_init
alloc_primitive_hex_unit "Int 42"
alloc_primitive_hex_unit "Sym toto"
alloc_cons_ptr_ptr_unit 1 $heap_max
printf '(+ 1 ( + 22 345 ))' | \
od -v -A n -t x1 | sed -e 's/^ //' | tr ' ' \\n | (while read c; do
case "$c" in
# Open paren
28) if test "x$(stack_peek_name_hex parse)" = 'x'; then
stack_pop_name_result_unit parse current
fi
stack_push_name_hex_unit parse 2028
stack_push_name_hex_unit parse '';;
# Close paren
29) if test "x$(stack_peek_name_hex parse)" = 'x'; then
stack_pop_name_result_unit parse current
else
stack_pop_name_result_unit parse current
alloc_primitive_hex_unit "Sym $current"
stack_push_name_hex_unit parse $heap_max
fi
alloc_primitive_hex_unit "Nil"
cdr=$heap_max
while test "x$(stack_peek_name_hex parse)" != 'x2028'; do
stack_pop_name_result_unit parse current
car=$current
alloc_cons_ptr_ptr_unit $car $cdr
cdr=$heap_max
done
stack_pop_name_result_unit parse current
stack_push_name_hex_unit parse $cdr;;
# Space
20) if test "x$(stack_peek_name_hex parse)" != 'x'; then
stack_pop_name_result_unit parse current
alloc_primitive_hex_unit "Sym $current"
stack_push_name_hex_unit parse $heap_max
stack_push_name_hex_unit parse ''
fi;;
# identifier character
*) stack_pop_name_result_unit parse current
stack_push_name_hex_unit parse "$current$c";;
esac
done
echo stack:
while test "x$(stack_len_name_int parse)" != 'x0'; do
stack_pop_name_result_unit parse tmp
echo "$tmp"
done | tac
echo heap:
for i in `seq $heap_max`; do
eval "echo $i \$heap_type_$i \$heap_car_$i \$heap_cdr_$i \$heap_value_$i"
done
#echo $(value $(cdr $heap_max))
debug_print $heap_max
echo
)

130
micro-scheme/nano-scheme.sh Executable file
View File

@ -0,0 +1,130 @@
#!/bin/sh
# Scheme syntax:
#
# ()lrwqicntfexyz
#
# ( start list
# ) end list
# l lambda
# r read byte
# w write byte
# b quote next byte in the source
# q quotes its argument
# i byte to int
# c cons
# n null
# t true
# f false
# e eq?
# x user variable (shadowing not allowed)
# y user variable (shadowing not allowed)
# z user variable (shadowing not allowed)
# TODO: free, GC roots, alloc, function pointers, …
#
# sh variables:
#
# a answer
# c lexer current char
# h heap_max
# t$i heap_type[$i]
# v$i heap_value[$i]
# d$i heap_cdr[$i]
#
# heap types:
#
# type v d
# P pair ptr ptr
# N null "_"
# F free cell ptr
# I integer int
# Y symbol hex
#
# Note: hex strings must not contain any spaces.
h=0
s=0
heap_sbrk() { h=$(($h+1)); }
heap_get_type() { eval a=\$t$1; }
heap_get_val() { eval a=\$v$1; }
heap_get_cdr() { eval a=\$d$1; }
heap_set() { eval t$1=$2; eval v$1=$3; }
heap_set_pair() { eval t$1=$2; eval v$1=$3; eval d$1=$4; }
heap_debug() { for heap_debug_i in `seq $h`; do
printf %s" " $heap_debug_i
heap_get_type $heap_debug_i; printf %s" " $a
heap_get_val $heap_debug_i; printf %s" " $a
heap_get_cdr $heap_debug_i; printf %s\\n $a
done }
stack_debug() { for stack_debug_i in `seq $s`; do
printf "<%s " $stack_debug_i
eval a=\$s$stack_debug_i
printf "%s>" $a
done
printf \\n; }
rlist() {
heap_sbrk; heap_set $h N _
rlist_cdr=$h
eval a=\$s$s
while test "$a" != M && test $s -ge 0; do
heap_sbrk; heap_set_pair $h P $a $rlist_cdr
rlist_cdr=$h
s=$(($s-1))
eval a=\$s$s
done
if test $s -lt 0; then
printf 'Parse error: unbalanced parenthesis'\\n
exit 1
fi
eval s$s=$rlist_cdr
}
debug_print() {
heap_get_type $1
if test $a = P; then
if $2; then printf %s ' '; else printf %s '('; fi
heap_get_val $1
debug_print $a false
heap_get_cdr $1
debug_print $a true
if $2; then :; else printf %s ')'; fi
elif test $a = N; then
if $2; then :; else printf %s '()'; fi
elif test $a = Y; then
if $2; then printf %s '.'; fi
heap_get_val $1
printf %s $a | xxd -ps -r
if $2; then printf %s ')'; fi
else
if $2; then printf %s '.'; fi
printf %s $a
heap_get_val $1
printf %s $a
heap_get_cdr $1
printf %s $a
if $2; then printf %s ')'; fi
fi
}
main() {
printf '(w((lxx)r))' \
| od -v -A n -t x1 \
| sed -e 's/^ //' \
| tr ' ' \\n \
| (while read c; do
echo lex:$c
case "$c" in
28) s=$(($s+1)); eval s$s=M ;;
29) stack_debug; rlist; stack_debug ;;
*) heap_sbrk; heap_set $h Y $c; s=$(($s+1)); eval s$s=$h ;;
esac
done
heap_debug
debug_print $h false)
}
if true; then main; exit $?; fi

21
references.md Normal file
View File

@ -0,0 +1,21 @@
* [9780751305418](https://isbnsearch.com/isbn/9780751305418) Dorling Kindersley Multimedia The Complete User-Friendly Guide to the Internet, World Wide Web, DVDs, Virtual Reality, CD-ROMs and 3D Games
This is an overview of the professions and techniques involved in the creation of interactive multimedia software. It fits well as a welcome guide for new employes, to let them know what the other professions are doing in the company, or as a pamhplet for students interested in joining a school training them for these professions.
* The Humane interface Jeff Raskin
* The psychology of computer programming silver anniversary edition
# Hardware
## Keyboard
* N-shot injection keycaps:
* [![double-shot injection keycaps cut in half to expose the two plastic parts](https://i.imgur.com/kVQNa.jpg)](https://imgur.com/a/OhRd4)
* [The best mechanical keycaps](https://blog.wooting.nl/what-are-the-best-mechanical-keyboard-keycaps), a presentation of various properties of keycaps
* [![Quadruple-shot injection keycap with two colors for the label and transparent plastic for caps lock or scroll lock indicator](https://deskauthority.net/download/file.php?id=5573)](https://deskauthority.net/viewtopic.php?p=80654#p80654)
* Planck [![Example layout of a planck keyboard](https://i.imgur.com/cNipMSc.png)](https://i.imgur.com/cNipMSc.png)
* [WASD Keyboards](https://www.wasdkeyboards.com/) does full-color print on keycaps. Examples:
[![illustrations (planets and space decor) on keys](https://i.imgur.com/F3lgqHJ.jpg)](https://i.imgur.com/F3lgqHJ.jpg)
[![Video editing software shortcuts](https://66.media.tumblr.com/9e8cbe7747b696822570ce0329f92fa1/tumblr_noo0x0SAcK1u475ako1_1280.jpg)](https://wasdkeyboards.tumblr.com/image/120541521288)
[![On-key characters for greek, mathematical symbols and other languages accessible via XCompose](https://i.imgur.com/21OoXw0.jpg)](https://imgur.com/a/DpQHW)
* Manufacturers and sellers:
* [Massdrop](https://www.massdrop.com/) gathers enthusiasts to buy medium-sized batches of random items (including keybords) to reduce the costs of small series that would not be commercialy viaable otherwise.

View File

@ -0,0 +1 @@
# Uniform interface to many emulators and virtual machines (QEMU, Bochs, VirtualBox, chroot, …)

View File

@ -0,0 +1,3 @@
Reasonably fast search of an image in a larger one.
Used for GUI tests (e.g. to detect whether a button appears and click on it with xdotool).

View File

@ -0,0 +1,5 @@
Exports all necessary source using the human-readable bootstrappable archive format
Builds the result using several executable stubs
Checks that the results are identical to the expected one.

View File

@ -0,0 +1 @@
Tests which run the OS on many emulators or platforms.

83
travis/auto-push.sh Executable file
View File

@ -0,0 +1,83 @@
#!/bin/sh
set -e
set +x # do not display any command, as they could contain the Travis openssl key and IV.
usage() {
echo "Usage: $0 official_repo deploy_repo deploy_branch deploy_base_commit key_iv_id deploy_directory"
echo "official_repo: https://github.com/user/repo.git"
echo "deploy_repo: git@github.com:user/repo.git"
echo "deploy_branch: gh-pages"
echo "deploy_base_commit: branch name or tag"
echo "key_iv_id: 123456789abc, part of encrypted_123456789abc_key and encrypted_123456789abc_iv"
echo "deploy_directory: directory to copy on top of deploy_base_commit"
echo "from_branch: master # allow push only when building the given branch"
}
if test "$#" -eq 1 && test "$1" = "-h" -o "$1" = "--help"; then
usage
exit 0
elif test "$#" -ne 7; then
usage
exit 1
fi
official_repo="$1" # https://github.com/user/repo.git
deploy_repo="$2" # git@github.com:user/repo.git
deploy_branch="$3" # gh-pages
deploy_base_commit="$4" # branch name or tag
key_iv_id="$5" # 123456789abc, part of encrypted_123456789abc_key and encrypted_123456789abc_iv
deploy_directory="$6" # directory to copy on top of deploy_base_commit
from_branch="$7" # master # allow push only when building the given branch
key_env_var_name="encrypted_${key_iv_id}_key"
iv_env_var_name="encrypted_${key_iv_id}_iv"
key="$(sh -c 'echo "${'"$key_env_var_name"'}"')"
iv="$(sh -c 'echo "${'"$iv_env_var_name"'}"')"
if test "$(git config remote.origin.url)" != "$official_repo"; then
echo "Not on official repo, will not deploy to ${deploy_repo}:${deploy_branch}."
elif test "$TRAVIS_PULL_REQUEST" != "false"; then
echo "This is a Pull Request, will not deploy to ${deploy_repo}:${deploy_branch}."
elif test "$TRAVIS_BRANCH" != "$from_branch"; then
echo "Not on $from_branch branch (TRAVIS_BRANCH = $TRAVIS_BRANCH), will not deploy to ${deploy_repo}:${deploy_branch}."
elif test -z "${key:-}" -o -z "${iv:-}"; then
echo "Travis CI secure environment variables are unavailable, will not deploy to ${deploy_repo}:${deploy_branch}."
elif test ! -e travis-deploy-key-id_rsa.enc; then
echo "travis-deploy-key-id_rsa.enc not present, will not deploy to ${deploy_repo}:${deploy_branch}."
else
echo "Automatic push to ${deploy_repo}:${deploy_branch}"
# Git configuration:
git config --global user.name "$(git log --format="%aN" HEAD -1) (Travis CI automatic commit)"
git config --global user.email "$(git log --format="%aE" HEAD -1)"
# SSH configuration
mkdir -p ~/.ssh
chmod 700 ~/.ssh
if openssl aes-256-cbc -K "$key" -iv "$iv" -in travis-deploy-key-id_rsa.enc -out travis-deploy-key-id_rsa -d >/dev/null 2>&1; then
echo "Decrypted key successfully."
else
echo "Error while decrypting key."
exit 1
fi
# TODO: all the config should be in a separate folder, instead of using ~/.ssh for the id_rsa.
mv travis-deploy-key-id_rsa ~/.ssh/travis-deploy-key-id_rsa
chmod 600 ~/.ssh/travis-deploy-key-id_rsa
eval `ssh-agent -s`
ssh-add ~/.ssh/travis-deploy-key-id_rsa
travis_known_hosts="$("$(dirname "$0")/absolute-path.sh" "$(dirname "$0")/travis_known_hosts")"
chmod 600 "$travis_known_hosts"
echo "$travis_known_hosts"
cat "$travis_known_hosts"
ssh -o UserKnownHostsFile=$travis_known_hosts git@github.com || true
TRAVIS_AUTO_PUSH_REPO_DIR="$HOME/travis-temp-auto-push-$(date +%s)"
if test -e "$TRAVIS_AUTO_PUSH_REPO_DIR"; then rm -rf "$TRAVIS_AUTO_PUSH_REPO_DIR"; fi
GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=$travis_known_hosts" git clone -b "$deploy_base_commit" --depth 1 --shallow-submodules "$deploy_repo" "$TRAVIS_AUTO_PUSH_REPO_DIR"
(cd "$TRAVIS_AUTO_PUSH_REPO_DIR" && git checkout -b "$deploy_branch")
rsync -a "${deploy_directory}/" "${TRAVIS_AUTO_PUSH_REPO_DIR}/"
(cd "$TRAVIS_AUTO_PUSH_REPO_DIR" && git add -A . && git commit --allow-empty -m "Auto-publish to $deploy_branch") > commit.log || (cat commit.log && exit 1)
(cd "$TRAVIS_AUTO_PUSH_REPO_DIR" && git log --oneline --decorate --graph -10)
echo '(cd '"$TRAVIS_AUTO_PUSH_REPO_DIR"' && git push --force --quiet "'"$deploy_repo"'" "'"$deploy_branch"'")'
(cd "$TRAVIS_AUTO_PUSH_REPO_DIR" && GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=$travis_known_hosts" git push --force --quiet "$deploy_repo" "$deploy_branch" >/dev/null 2>&1) >/dev/null 2>&1 # redirect to /dev/null to avoid showing credentials.
fi

1
vm/README.md Normal file
View File

@ -0,0 +1 @@
A simple virtual machine (in the programming language runtime sense), used to abstract many hardware backends.