[Spice-commits] 4 commits - Makefile.am configure.ac docs/Makefile.am docs/spice_protocol.txt m4/spice_manual.m4

Frediano Ziglio fziglio at kemper.freedesktop.org
Mon Oct 17 10:44:08 UTC 2016


 Makefile.am             |    2 
 configure.ac            |    2 
 docs/Makefile.am        |   17 +
 docs/spice_protocol.txt |  423 ++++++++++++++++++++++++++++++++++++++++++++++++
 m4/spice_manual.m4      |   32 +++
 5 files changed, 475 insertions(+), 1 deletion(-)

New commits:
commit 4673a61cce1c81da7b4f5e2239484b57c1a4be8a
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Sep 19 14:11:51 2016 +0100

    More work on attribute protocol documentation
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/docs/spice_protocol.txt b/docs/spice_protocol.txt
index 832ea73..13506f1 100644
--- a/docs/spice_protocol.txt
+++ b/docs/spice_protocol.txt
@@ -336,12 +336,21 @@ TODO
 nomarshal
 ~~~~~~~~~
 
-TODO
+Do not generate code for marshalling this variable.
+Usually used on last array element to make possible to manually feed data.
+
+Example:
+    struct Data {
+        uint32 data_size;
+        uint8 data[data_size] @nomarshal;
+    };
 
 zero_terminated
 ~~~~~~~~~~~~~~~
 
-TODO
+The field should terminated by zero.
+Actually it's not used by python code so it's not enforced and no
+code is generated.
 
 marshall
 ~~~~~~~~
@@ -351,12 +360,16 @@ TODO
 nonnull
 ~~~~~~~
 
-TODO
+This pointer field cannot be NULL. This means that marshaller assume C structure
+contain not NULL pointer and demarshaller will fail to demarshall message if offset
+is 0.
 
 unique_flag
 ~~~~~~~~~~~
 
-TODO
+This flag field should contain just a single flag.
+Actually it's not used by python code so it's not enforced and no
+code is generated.
 
 ptr_array
 ~~~~~~~~~
commit 7773c0d59b0384237b549484da9cc8cac274cf58
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Sun Sep 18 14:37:07 2016 +0100

    Extended protocol documentation
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/docs/spice_protocol.txt b/docs/spice_protocol.txt
index 3406cb9..832ea73 100644
--- a/docs/spice_protocol.txt
+++ b/docs/spice_protocol.txt
@@ -23,6 +23,8 @@ It resemble the C format.
 
 (here BNF with some regular expression is used).
 
+It's used to generate automatically code to marshall/demarshall the network data.
+
 Example:
 
     channel ExampleChannel {
@@ -47,4 +49,362 @@ Both C and C++ style comments are supported
     /* this is a comment too
        but can be split in multiple lines */
 
+Base types
+----------
+
+All int from 8 to 64 bit (8, 16, 32 and 64) are supported either signed or unsigned.
+Also you can pass one unix descriptor.
+
+    base_type ::= "int8"|"uint8"|"int16"|"uint16"|"int32"|"uint32"|"int64"|"uint64"|"unix_fd" ;
+
+Example:
+
+    int16 x;
+
+Enumerations and flags
+----------------------
+
+It's possible to specify enumerations and flags. The difference is that flags are defined as 2 power
+values and can combined. Enumerations and flags must have a size (`8`, `16` or `32`) specified.
+
+    enum ::= <enum_type> "{" [ <enumflag_items> ] "}" <attributes> ";" ;
+    flag ::= <flag_type> "{" [ <enumflag_items> ] "}" <attributes> ";" ;
+    enum_type ::= "enum8"|"enum16"|"enum32" ;
+    flag_type ::= "flag8"|"flag16"|"flag32" ;
+    enumflag_items ::= <enumflag_item>|<enumflag_items><enumflag_item>
+    enumflag_item ::= <enum_name> [ "=" <integer> ] [ "," ] ;
+    enum_name ::= [a-z0-9_]* ;
+
+Example:
+
+    enum16 Level {
+        LOW = 0x100,
+        MEDIUM,
+        HIGH = 0x1000
+    };
+
+Variables
+---------
+
+As you should already have noted variables are similar to C syntax but there are
+some differences.
+
+    variable ::= <type> [ "*" ] <identifier> [ "[" <array_size> "]" ] <attributes>;
+
+The `*` specify a pointer. This is quite different from C. For the protocol it
+specifies that in the protocol stream a relative offset is put that points to that
+variable usually after all defined fields. This happens even on arrays, so for instance
+
+    int32 *n;
+
+containing a 0x12345678 `n` value could ended up coded as
+
+    04 00 00 00 // 4 as offset
+    78 56 34 12 // `n`
+
+(little endian). While an array of 2 items defined as
+
+    int32 *n[2];
+
+and containing 0x12345678 and 0x9abcdef could end up with
+
+    04 00 00 00 // 4 as offset
+    78 56 34 12 // `n`[0]
+    ef cd ab 09 // `n`[1]
+
+note that `int32 *n[2]` defined a pointer to an array of 2 items and not
+an array of pointers as C.
+
+*WARNING*: You should avoid using pointers on protocol if not necessary as they are complicated
+to handle not using autogenerated code and also use more space on the network.
+
+Arrays
+------
+
+As seen above the easiest way to define an array size is specifiying a constant value.
+However there are multiple way to specify the size
+
+    array_size ::= <integer>|<identifier>|""|<array_size_image>|<array_size_bytes>|<array_size_cstring> ;
+    array_size_image ::= "image_size" "(" <integer> "," <identifier> ")" ;
+    array_size_bytes ::= "bytes" "(" <identifier> "," <identifier> ")" ;
+    array_size_cstring ::= "cstring()" ;
+
+We already seen integer.
+Specifying an identifier name instead (should be variable) indicate that the length is specified
+in another field, for instance
+
+    uint8 name_len;
+    int8 name[name_len];
+
+allows to put a name of `name_len` len.
+The empty value tell that the array will end when the containing message end so if we have
+
+    int8 name[];
+
+and the message is
+
+    66 6f 6f
+
+possibly the name we want is `foo` (66 6f 6f is the ASCII encoding for `foo`).
+
+TODO: what happen with two [] in the structure ??
+TODO: can a [] array not be the last and what happens ??
+
+`image_size` allow to specify an array holding an image, for instance
+
+    uint16 width;
+    uint16 heigth;
+    uin18 raw_image[image_size(8, width, height)];
+
+could contain row data in raw_image. The constant `8` is the bit size of the image.
+
+TODO `bytes`
+
+`cstring` allows to specify NUL-terminated sequence so having
+
+    int8 name[cstring()];
+
+and the message as
+
+    66 6f 6f 00
+
+we'll have the `foo` name. Note that the field does not need to end the message as in `int8 name[]` example.
+
+Structures
+----------
+
+The simpler coumpound type is the structure. As in C is defined as a list of fields (any variable or swicth).
+But as a protocol definition there are no alignment or padding and every field (beside pointer values) follow each other.
+
+    <struct> ::= "struct" <identifier> "{" [ <fields> ] "}" <attributes> ";" ;
+    <fields> ::= <field>|<fields><field> ;
+    <field> ::= <variable>|<switch>
+
+Example:
+
+    struct Point {
+        int32 x;
+        int32 y;
+    };
+
+Messages
+--------
+
+Messages have the same syntax of structure (beside `message`) with the different that they can
+be used directly inside channels.
+
+    <message> ::= "message" <identifier> "{" [ <fields> ] "}" <attributes> ";" ;
+
+Switches
+--------
+
+TODO
+
+Type definitions
+----------------
+
+Like C type definition allow to short types defining new ones.
+
+    <typedef> ::= "typedef" <identifier> <type>`<attributes> ;
+
+note that unlike C name came before the type.
+
+Example:
+
+    typedef XCoord int32;
+
+Channels
+--------
+
+TODO
+
+Attributes
+----------
+
+As you probably noted attributed can be specified for lot of definitions.
+They allow to change code generated or specific contraints to the protocol.
+
+    attributes ::= ""|<attributes><attribute>|<attribute> ;
+    attribute ::= <attribute_name> [ "(" <attribute_values> ")" ] ;
+    attribute_values ::= <attribute_values> "," <attribute_value> | <attribute_value>
+    attribute_value ::= <integer> | <identifier>
+    attribute_name ::= @[a-z][a-z0-9_]* ;
+
+Mostly of the attributes have no arguments, other currently have only one
+argument.
+
+*NOTE*: Some comments are also written in `spice-common` `python_modules/ptypes.py`
+source file.
+
+ctype
+~~~~~
+
+Specify the structure type name that the generated marshaller/demarshaller code
+will use. By default the name will be converted to CamelCase and prefixed by
+`Spice` so for example a structure like
+
+    struct Point {
+        int32 x;
+        int32 y;
+    } @ctype(MyPoint);
+
+will be marshalled into a C structure like
+
+    struct MyPoint {
+        int32_t x;
+        int32_t y;
+    };
+
+prefix
+~~~~~~
+
+This attribute allow to specify the prefix used for generated enumerations (both
+protocol enumerations and flags generate C enumerations). By default the enumeration
+will use upper case of the enum/flag name prefixed with `SPICE_` and followed by item so
+
+    enum32 level {
+        LOW,
+        HIGH,
+    };
+
+will generate
+
+    typedef enum SpiceLevel {
+        SPICE_LEVEL_LOW,
+        SPICE_LEVEL_HIGH,
+        SPICE_LEVEL_ENUM_END
+    } SpiceLevel;
+
+while
+
+    enum32 level {
+        LOW,
+        HIGH,
+    } @prefix(LVL_);
+
+will generate
+
+    typedef enum SpiceLevel {
+        LVL_LOW,
+        LVL_HIGH,
+        SPICE_LEVEL_ENUM_END
+    } SpiceLevel;
+
+(note that an automatic `END` enumeration is generated and name is not affected).
+
+end
+~~~
+
+This attribute specify that the data will be appended/embedded in the final C structure.
+
+Example:
+
+    struct test {
+        uint16 len;
+        uint16 array[len] @end;
+    };
+
+Output C structure:
+
+    struct test {
+        uint16_t len;
+        uint16_t array[0];
+    };
+
+The generated code will allocate the C structure to allow space for extracted array.
+
+*WARNING*: This option is usually confused with with empty size protocol. The
+empty protocol array size specify array that extend on the network data while
+the `@end` attribute specify to extend the C structure (for instance in the example
+the attribute was attached to a `len`-sized array).
+
+to_ptr
+~~~~~~
+
+TODO
+
+nocopy
+~~~~~~
+
+TODO
+
+as_ptr
+~~~~~~
+
+TODO
+
+nomarshal
+~~~~~~~~~
+
+TODO
+
+zero_terminated
+~~~~~~~~~~~~~~~
+
+TODO
+
+marshall
+~~~~~~~~
+
+TODO
+
+nonnull
+~~~~~~~
+
+TODO
+
+unique_flag
+~~~~~~~~~~~
+
+TODO
+
+ptr_array
+~~~~~~~~~
+
+TODO
+
+outvar
+~~~~~~
+
+TODO
+
+anon
+~~~~
+
+TODO
+
+chunk
+~~~~~
+
+TODO
+
+ifdef
+~~~~~
+
+TODO
+
+zero
+~~~~
+
+TODO
+
+minor
+~~~~~
+
+TODO
+
+bytes_count
+~~~~~~~~~~~
+
+TODO
+
+virtual
+~~~~~~~
+
+TODO
+
+fixedsize
+~~~~~~~~~
+
+TODO
 
commit 89426e491e5c217846c50ae3d3e320f36291e71f
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Fri Sep 9 10:40:29 2016 +0100

    Start writing some documentation on protocol
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/docs/spice_protocol.txt b/docs/spice_protocol.txt
index b62da25..3406cb9 100644
--- a/docs/spice_protocol.txt
+++ b/docs/spice_protocol.txt
@@ -1,2 +1,50 @@
 Spice protocol format file
 ==========================
+
+Copyright (C) 2016 Red Hat, Inc.
+Licensed under a Creative Commons Attribution-Share Alike 3.0
+United States License (see http://creativecommons.org/licenses/by-sa/3.0/us/legalcode).
+
+Basic
+-----
+The spice protocol format file defines the network protocol used by spice.
+It resemble the C format.
+
+    file ::= <definitions> <protocol> ;
+    definitions ::= <definition>|<definitions><definition> ;
+    definition ::= <typedef>|<structure>|<enum>|<flag>|<message>|<channel> ;
+    protocol ::= "protocol" <identifier> "{" <protocol_channels> "}" ";" ;
+    protocol_channels ::= <protocol_channel>|<protocol_channels><protocol_channel> ;
+    protocol_channel ::= <identifier> <identifier> [ "=" <integer> ] ";" ;
+    integer ::= <hex>|<dec> ;
+    dec ::= [+-][0-9]+ ;
+    hex ::= "0x" [0-9a-f]+ ;
+    identifier ::= [a-z][a-z0-9_]* ;
+
+(here BNF with some regular expression is used).
+
+Example:
+
+    channel ExampleChannel {
+       message {
+          uint32 dummy;
+       } Dummy;
+    };
+
+    protocol Example {
+        ExampleChannel first = 1001;
+    };
+
+As you can see brackets like C are used and structures looks like C but you
+can also see that keyworks like `channel`, `protocol`, `message` or some
+predefined types like `uint32` are proper of the protocol.
+
+Comments
+--------
+Both C and C++ style comments are supported
+
+    // this is a comment
+    /* this is a comment too
+       but can be split in multiple lines */
+
+
commit 3983097ed505901abed0eb7fda70ece1631aaa24
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Fri Sep 9 10:39:40 2016 +0100

    Start adding protocol file documentation
    
    The protocol file is not documented and people have to read code to
    understand the specification.
    This can lead to unexpected or not optimal results so it's better
    to have it documented.
    The m4/spice_manual.m4 came from spice server and is meant to be
    reused.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/Makefile.am b/Makefile.am
index 63d7956..ee0a1e2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
 NULL =
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = python_modules common tests
+SUBDIRS = python_modules common tests docs
 
 EXTRA_DIST =				\
 	spice_codegen.py		\
diff --git a/configure.ac b/configure.ac
index c3ad5a4..6d9f378 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,7 @@ AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip tar-ustar foreign -Wall -Werror])
 AM_MAINTAINER_MODE
 AM_SILENT_RULES([yes])
 LT_INIT
+SPICE_MANUAL
 
 AC_PROG_CC
 AC_PROG_CC_C99
@@ -50,6 +51,7 @@ AC_CONFIG_FILES([
   common/Makefile
   python_modules/Makefile
   tests/Makefile
+  docs/Makefile
 ])
 
 AH_BOTTOM([
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 0000000..0b09b82
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,17 @@
+NULL =
+ASCIIDOC_FLAGS = -a icons -a toc
+
+EXTRA_DIST =					\
+	spice_protocol.html			\
+	spice_protocol.txt			\
+	$(NULL)
+
+if BUILD_HTML_MANUAL
+all-local: spice_protocol.html
+
+spice_protocol.html: spice_protocol.txt
+	$(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $<
+endif
+
+clean-local:
+	rm -f spice_protocol.html
diff --git a/docs/spice_protocol.txt b/docs/spice_protocol.txt
new file mode 100644
index 0000000..b62da25
--- /dev/null
+++ b/docs/spice_protocol.txt
@@ -0,0 +1,2 @@
+Spice protocol format file
+==========================
diff --git a/m4/spice_manual.m4 b/m4/spice_manual.m4
new file mode 100644
index 0000000..c36f6f7
--- /dev/null
+++ b/m4/spice_manual.m4
@@ -0,0 +1,32 @@
+dnl SPICE_MANUAL
+dnl ------------
+dnl Check if user wants manuals to be compiled and
+dnl if all programs (asciidoc and a2x) are available
+dnl ------------
+dnl Shell defines:
+dnl - have_asciidoc yes or not is asciidoc program is available
+dnl Automake macros:
+dnl - A2X a2x program or empty
+dnl - ASCIIDOC asciidoc program or emtpy
+dnl - BUILD_MANUAL if asciidoc and a2x are available
+dnl - BUILD_HTML_MANUAL if asciidoc is available (html can be produced)
+dnl - BUILD_CHUNKED_MANUAL if a2x is available
+AC_DEFUN([SPICE_MANUAL],[
+    AC_ARG_ENABLE([manual],
+                   AS_HELP_STRING([--enable-manual=@<:@auto/yes/no@:>@],
+                                  [Build SPICE manual]),
+                   [],
+                   [enable_manual="auto"])
+    if test "x$enable_manual" != "xno"; then
+        AC_PATH_PROG([ASCIIDOC], [asciidoc])
+        AS_IF([test -z "$ASCIIDOC" && test "x$enable_manual" = "xyes"],
+              [AC_MSG_ERROR([asciidoc is missing and build of manual was requested])])
+        AC_PATH_PROG([A2X], [a2x])
+        AS_IF([test -z "$A2X" && test "x$enable_manual" = "xyes"],
+              [AC_MSG_ERROR([a2x is missing and build of manual was requested])])
+    fi
+    AS_IF([test -n "$ASCIIDOC"], [have_asciidoc=yes], [have_asciidoc=no])
+    AM_CONDITIONAL([BUILD_MANUAL], [test -n "$ASCIIDOC" || test -n "$A2X"])
+    AM_CONDITIONAL([BUILD_HTML_MANUAL], [test -n "$ASCIIDOC"])
+    AM_CONDITIONAL([BUILD_CHUNKED_MANUAL], [test -n "$A2X"])
+])


More information about the Spice-commits mailing list