summaryrefslogtreecommitdiffstats
path: root/README.adoc
blob: 765685cf660b11aa16a1c709b881486331aa7e08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
= S-Expressions parser and generator library in C\++ (SEXP in C++)

image:https://github.com/rnpgp/sexp/workflows/build-and-test/badge.svg["Build status Ubuntu/macOS/Windows", link="https://github.com/rnpgp/sexp/actions?workflow=build-and-test"]
image:https://github.com/rnpgp/sexp/workflows/build-and-test-rh/badge.svg["Build status CentOS/Fedora", link="https://github.com/rnpgp/sexp/actions?workflow=build-and-test-rh"]
image:https://github.com/rnpgp/sexp/workflows/build-and-test-deb/badge.svg["Build status Debian", link="https://github.com/rnpgp/sexp/actions?workflow=build-and-test-deb"]
image:https://github.com/rnpgp/sexp/workflows/build-and-test-msys/badge.svg["Build status MSys", link="https://github.com/rnpgp/sexp/actions?workflow=build-and-test-msys"]


image:https://codecov.io/gh/rnpgp/sexpp/branch/main/graph/badge.svg["Code coverage", link="https://codecov.io/gh/rnpgp/sexpp"]
image:https://github.com/rnpgp/sexpp/workflows/CodeQL/badge.svg["CodeQL analysis", link="https://github.com/rnpgp/sexpp/actions?workflow=CodeQL"]
image:https://scan.coverity.com/projects/28717/badge.svg["Coverity Scan Build Status", link="https://scan.coverity.com/projects/rnpgp-sexpp"]


== Purpose

This is a C++ library for working with S-Expressions.

This implementation is derived from the reference SEXP C library developed by
Prof. Ronald Rivest and Prof. Butler Lampson of MIT LCS (now CSAIL).

This library differs from the original C implementation in the following ways:

* It aims to be reuseable in C++ implementations and is importable via CMake.
* It includes a test suite for correctness testing and tests against malformed
  S-Expressions.
* It supports, and is tested against, all major platforms, including:
** Ubuntu, Debian, Fedora, CentOS
** macOS
** Windows
** msys
* It implements additional interface to work with S-Expressions wrapped by GnuPG
  2.3+ extended format
  (https://github.com/gpg/gnupg/blob/master/agent/keyformat.txt[specification]).


The original C library was available at (but no longer accessible):

* http://people.csail.mit.edu/rivest/sexp.html


== Background

S-Expressions are a data structure for representing complex data as a variation
on https://en.wikipedia.org/wiki/Lisp_(programming_language)[LISP] S-Expressions.

S-Expressions were originally adopted for use in
http://theory.lcs.mit.edu/~cis/sdsi.html[SDSI] and
http://world.std.com/~cme/html/spki.html[SPKI].

SDSI has been developed by Prof.
https://people.csail.mit.edu/rivest/index.html[Ronald L. Rivest] and
Prof. Butler Lampson of
http://www.lcs.mit.edu/[MIT's Laboratory for Computer Science],
members of
http://theory.lcs.mit.edu/~cis[LCS's Cryptography and Information Security]
research group.

NOTE: SDSI research has been supported by DARPA contract DABT63-96-C-0018,
"Security for Distributed Computer Systems".

NOTE: SPKI has been developed by
http://www.clark.net/pub/cme/home.html[Carl Ellison] and others in the IETF SPKI
working group.


== S-Expressions specification

* https://datatracker.ietf.org/doc/draft-rivest-sexp/

NOTE: The "SEXP 1.0 guide" used to be at
https://people.csail.mit.edu/rivest/Sexp.txt.


== Code

The library is a deep rework to C++ of the original
https://people.csail.mit.edu/rivest/sexp.html[SEXP library] that maintains full
support of original specification.

While most applications will not need anything but the simple canonical and
transport formats; however, the code here is considerably more complex because
it also supports the advanced format, both for input and for output.


== Building and installation

[source,sh]
----
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
$ ctest
$ cmake --install .
----


== CMake script options

`BUILD_SHARED_LIBS:BOOL`::
(default: `OFF`)
build shared library

`WITH_SEXP_TESTS:BOOL`::
(default: `ON`)
build tests

`DOWNLOAD_GTEST`::
(default: `ON`)
if tests are built, automatically download googletest from GitHub;
when set to `OFF`, the googletest binary package needs to be available for SEXP
tests.

`WITH_SEXP_CLI:BOOL`::
(default: `ON`) build the `sexp` command-line utility

`WITH_SANITIZERS:BOOL`::
(default: `OFF`)
build with address and other sanitizers (requires clang compiler)



== SEXPP command-line utility

The `sexpp` command-line utility is reference parser and generator of
S-Expressions. It can read, parse and print out SEXP in all defined formats.

=== Switches

.`sexpp` switches
[options="header"]
|===
| Switch          | Description                                    | Default

3+| Input
| `-i <filename>` | input file name                                | read input from console (stdin)
| `-p`            | prompt input if reading from console           | disabled
| `-s`            | treat input as a single SEXP string            | disabled, input is treated as an S-Expression

3+| Output
| `-o <filename>` | output file name:                              | write output to console (stdout)
| `-a`            | generate advanced transport format             | enabled if no format is specified
| `-b`            | generate base-64 transport format              | disabled
| `-c`            | generate canonical format                      | disabled
| `-l`            | suppress linefeeds after output                | disabled
| `-w <width>`    | set output line width (0 implies no constraint)| 75

3+| Miscellaneous
| `-x`            | execute repeatedly until EOF                   | process single S-Expression then exit
| `-h`            | print help message and exit                    |

|===

Running without switches implies: `-p -a -b -c -x`.

=== Usage examples

Prompt for S-Expressions input from console, parse and output it to
`certificate.dat` in base64 transport format.

[source]
----
$ sexpp -o certificate.dat -p -b

> Input:
> (aa bb (cc dd))
>
> Writing base64 (of canonical) output to 'certificate.dat'
----

Parse all S-Expressions from `certificate.dat`, output them to console in
advanced transport format with no prompts:

[source,sh]
----
$ sexpp -i certificate.dat -x

> (2:aa2:bb(2:cc2:dd))
----

Parse S-Expressions from `certificate.dat`, output it to console in canonical,
base64 and advanced format with prompts and no width limitation:

[source,sh]
----
$ sexpp -i certificate.dat -a -b -c -p -w 0

> Reading input from certificate.dat
>
> Canonical output:
> (2:aa2:bb(2:cc2:dd))
> Base64 (of canonical) output:
> {KDI6YWEyOmJiKDI6Y2MyOmRkKSk=}
> Advanced transport output:
> (aa bb (cc dd))
----

Repeatedly prompt for S-Expressions input from console, parse and output it
console in advanced, base64 and canonical formats:

[source,sh]
----
$ sexpp -p -a -b -c -x
----

or just

[source,sh]
----
$ sexpp

> Input:
> (abc def (ghi jkl))
>
> Canonical output:
> (3:abc3:def(3:ghi3:jkl))
> Base64 (of canonical) output:
> {KDM6YWJjMzpkZWYoMzpnaGkzOmprbCkp}
> Advanced transport output:
> (abc def (ghi jkl))
>
> Input:
> ^C
----

== License

Copyright Ribose.

The code is made available as open-source software under the MIT License.