miniroon

Simplistic macaroon-based authorization for Unix systems
git clone https://ccx.te2000.cz/git/miniroon
Log | Files | Refs | README

commit 0115452a17b566c5810acfeb4bb16e0a353048f9
parent df11fb12eae38d88b7a219399a4fc5c1d81cf67a
Author: Jan Pobrislo <ccx@te2000.cz>
Date:   Thu, 24 Apr 2025 23:10:16 +0000

awk script for generating html of specification

Diffstat:
Adoc/Makefile | 3+++
Adoc/spec.html | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/spec.pl | 38+++++++++++++++++++-------------------
Adoc/spec2html.awk | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+), 19 deletions(-)

diff --git a/doc/Makefile b/doc/Makefile @@ -0,0 +1,3 @@ +spec.html: spec.pl spec2html.awk + awk -f spec2html.awk spec.pl >'$@.new' + mv '$@.new' '$@' diff --git a/doc/spec.html b/doc/spec.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html><body><table> +<tr><td>1</td><td><pre>:- use_module(library(error)).</pre></td><td rowspan="2"></td></tr> +<tr><td>2</td><td><pre>:- use_module(library(dcg/basics)).</pre></td></tr> +<tr><td>3</td><td><pre></pre></td><td rowspan="2"></td></tr> +<tr><td>4</td><td><pre>:- op(950, xfx, will_be).</pre></td></tr> +<tr><td>5</td><td><pre></pre></td><td rowspan="2"></td></tr> +<tr><td>6</td><td><pre>%%% Basic definitions</pre></td></tr> +<tr><td>7</td><td><pre></pre></td><td rowspan="4"></td></tr> +<tr><td>8</td><td><pre>% apply check to value when bound</pre></td></tr> +<tr><td>9</td><td><pre>will_be(Value, Goal) :-</pre></td></tr> +<tr><td>10</td><td><pre> freeze(Value, call(Goal, Value)).</pre></td></tr> +<tr><td>11</td><td><pre></pre></td><td rowspan="2"></td></tr> +<tr><td>12</td><td><pre>byte(Value) :- must_be(between(0, 255), Value).</pre></td></tr> +<tr><td>13</td><td><pre></pre></td><td rowspan="2"></td></tr> +<tr><td>14</td><td><pre>nonnegative_integer(Value) :- must_be(nonneg, Value).</pre></td></tr> +<tr><td>15</td><td><pre></pre></td><td rowspan="5"></td></tr> +<tr><td>16</td><td><pre>sequence_of_bytes([]).</pre></td></tr> +<tr><td>17</td><td><pre>sequence_of_bytes([First|Rest]) :-</pre></td></tr> +<tr><td>18</td><td><pre> First will_be byte,</pre></td></tr> +<tr><td>19</td><td><pre> Rest will_be sequence_of_bytes.</pre></td></tr> +<tr><td>20</td><td><pre></pre></td><td rowspan="1"></td></tr> +<tr><td>21</td><td><pre>netstring_encoding(PayloadLength, PayloadBytes) -->gt; %<lt; Netstring is a sequence of bytes.</pre></td><td rowspan="2"></td></tr> +<tr><td>22</td><td><pre> { length(PayloadBytes, PayloadLength) },</pre></td></tr> +<tr><td>23</td><td><pre> netstring_prefix(PayloadLength), %<lt; It consists of prefix,</pre></td><td rowspan="1"></td></tr> +<tr><td>24</td><td><pre> PayloadBytes, %<lt; payload,</pre></td><td rowspan="1"></td></tr> +<tr><td>25</td><td><pre> `,`. %<lt; and terminator. Terminator is single ASCII comma `,`.</pre></td><td rowspan="5"></td></tr> +<tr><td>26</td><td><pre>netstring_encoding(netstring(PayloadLength, PayloadBytes), Bytes) :-</pre></td></tr> +<tr><td>27</td><td><pre> Bytes will_be sequence_of_bytes,</pre></td></tr> +<tr><td>28</td><td><pre> PayloadLength will_be nonnegative_integer,</pre></td></tr> +<tr><td>29</td><td><pre> phrase(netstring_encoding(PayloadLength, PayloadBytes), Bytes).</pre></td></tr> +<tr><td>30</td><td><pre></pre></td><td rowspan="4"> +Netstring prefix is the shortest ASCII decimal representation for length of payload in bytes, followed by ASCII colon `:`. That is number starting with non-zero digit unless payload is empty, in which case it's `0`.</td></tr> +<tr><td>31</td><td><pre></pre></td></tr> +<tr><td>32</td><td><pre>netstring_prefix(0) -->gt; `0:`.</pre></td></tr> +<tr><td>33</td><td><pre>netstring_prefix(N) -->gt; positive_decimal(N), `:`.</pre></td></tr> +<tr><td>34</td><td><pre></pre></td><td rowspan="7"></td></tr> +<tr><td>35</td><td><pre>positive_decimal(N) -->gt;</pre></td></tr> +<tr><td>36</td><td><pre> { freeze(N, format(codes([C|Cs]), '~w', N)) },</pre></td></tr> +<tr><td>37</td><td><pre> nonzero_digit(C),</pre></td></tr> +<tr><td>38</td><td><pre> digits(Cs),</pre></td></tr> +<tr><td>39</td><td><pre> { phrase(number(N), [C|Cs]) }.</pre></td></tr> +<tr><td>40</td><td><pre>nonzero_digit(Code) -->gt; [Code], {member(Code, `123456789`)}.</pre></td></tr> +<tr><td>41</td><td><pre></pre></td><td rowspan="6"></td></tr> +<tr><td>42</td><td><pre>netstring_of(Goal, Bytes) :-</pre></td></tr> +<tr><td>43</td><td><pre> ground(Goal),</pre></td></tr> +<tr><td>44</td><td><pre> !,</pre></td></tr> +<tr><td>45</td><td><pre> call(Goal, PayloadBytes),</pre></td></tr> +<tr><td>46</td><td><pre> netstring_encoding(netstring(_, PayloadBytes), Bytes).</pre></td></tr> +<tr><td>47</td><td><pre></pre></td><td rowspan="6"></td></tr> +<tr><td>48</td><td><pre>netstring_of(Goal, Bytes) :-</pre></td></tr> +<tr><td>49</td><td><pre> ground(Bytes),</pre></td></tr> +<tr><td>50</td><td><pre> !,</pre></td></tr> +<tr><td>51</td><td><pre> netstring_encoding(netstring(_, PayloadBytes), Bytes),</pre></td></tr> +<tr><td>52</td><td><pre> call(Goal, PayloadBytes).</pre></td></tr> +<tr><td>53</td><td><pre></pre></td><td rowspan="1"></td></tr> +<tr><td>54</td><td><pre></pre></td><td rowspan="3"></td></tr> +<tr><td>55</td><td><pre>% :- use_module(library(pldoc/doc_files)).</pre></td></tr> +<tr><td>56</td><td><pre>% doc_save('spec.pl', [format(html), doc_root(.)]).</pre></td></tr> +</table></body></html> diff --git a/doc/spec.pl b/doc/spec.pl @@ -1,13 +1,15 @@ :- use_module(library(error)). -:- use_module(library(http/dcg_basics)). +:- use_module(library(dcg/basics)). :- op(950, xfx, will_be). -will_be(Value, Predicate) :- - freeze(Value, call(Predicate, Value)). +%%% Basic definitions + +% apply check to value when bound +will_be(Value, Goal) :- + freeze(Value, call(Goal, Value)). byte(Value) :- must_be(between(0, 255), Value). -% integer(Value), Value >= 0, Value <= 255. nonnegative_integer(Value) :- must_be(nonneg, Value). @@ -15,30 +17,27 @@ sequence_of_bytes([]). sequence_of_bytes([First|Rest]) :- First will_be byte, Rest will_be sequence_of_bytes. -% freeze(First, byte(First)), -% freeze(Rest, sequence_of_bytes(Rest)). +netstring_encoding(PayloadLength, PayloadBytes) --> %< Netstring is a sequence of bytes. + { length(PayloadBytes, PayloadLength) }, + netstring_prefix(PayloadLength), %< It consists of prefix, + PayloadBytes, %< payload, + `,`. %< and terminator. Terminator is single ASCII comma `,`. netstring_encoding(netstring(PayloadLength, PayloadBytes), Bytes) :- Bytes will_be sequence_of_bytes, PayloadLength will_be nonnegative_integer, - % freeze(Bytes, sequence_of_bytes(Bytes)), - % freeze(PayloadLength, integer(PayloadLength)). phrase(netstring_encoding(PayloadLength, PayloadBytes), Bytes). -%length(Payload, PayloadLength), -netstring_encoding(PayloadLength, PayloadBytes) --> - {length(PayloadBytes, PayloadLength)}, - netstring_prefix(PayloadLength), - PayloadBytes, - `,`. -nonzero_digit(Code) --> [Code], {member(Code, `123456789`)}. +%> Netstring prefix is the shortest ASCII decimal representation for length of payload in bytes, followed by ASCII colon `:`. That is number starting with non-zero digit unless payload is empty, in which case it's `0`. +netstring_prefix(0) --> `0:`. +netstring_prefix(N) --> positive_decimal(N), `:`. + positive_decimal(N) --> - {freeze(N, format(codes([C|Cs]), '~w', N))}, + { freeze(N, format(codes([C|Cs]), '~w', N)) }, nonzero_digit(C), digits(Cs), - {phrase(number(N), [C|Cs])}. -netstring_prefix(0) --> `0:`. -netstring_prefix(N) --> positive_decimal(N), `:`. + { phrase(number(N), [C|Cs]) }. +nonzero_digit(Code) --> [Code], {member(Code, `123456789`)}. netstring_of(Goal, Bytes) :- ground(Goal), @@ -52,5 +51,6 @@ netstring_of(Goal, Bytes) :- netstring_encoding(netstring(_, PayloadBytes), Bytes), call(Goal, PayloadBytes). + % :- use_module(library(pldoc/doc_files)). % doc_save('spec.pl', [format(html), doc_root(.)]). diff --git a/doc/spec2html.awk b/doc/spec2html.awk @@ -0,0 +1,54 @@ +#!/usr/bin/awk -f + +BEGIN { + FS="%[>^] " + printf("%s\n", "<!DOCTYPE html>") + printf("%s\n", "<html><body><table>") + last_comm = 1 +} + +/%< / || /^$/{ + last_comm = NR +} + +{ + code[NR] = $1 + if(last_comm in comm) { + if(length($2)) { + comm[last_comm] = comm[last_comm] "\n" $2 + } + } else { + comm[last_comm] = $2 + } + span[last_comm] = span[last_comm] + 1 +} + +function entity_escape(s) { + gsub(/&/, "&amp;", s) + gsub(/</, "&lt;", s) + gsub(/>/, "&gt;", s) + return s +} + +function line(n){ + if(span[n]) { + printf("<tr><td>%d</td><td><pre>%s</pre></td><td rowspan=\"%d\">%s</td></tr>\n"\ + , n \ + , entity_escape(code[n]) \ + , span[n] \ + , entity_escape(comm[n]) \ + ) + } else { + printf("<tr><td>%d</td><td><pre>%s</pre></td></tr>\n"\ + , n \ + , entity_escape(code[n]) \ + ) + } +} + +END { + for(n=1; (n in code); n++) { + line(n) + } + printf("%s\n", "</table></body></html>"); +}