[libvirt] [PATCH v3 00/13] documentation improvements, code blocks with syntax highlighting

Hi. This is version 3 of https://www.redhat.com/archives/libvir-list/2013-January/msg02026.html combined with pre-requisite patches from https://www.redhat.com/archives/libvir-list/2013-January/msg02071.html Summary of the changes: - patch #1 to #4 are adding / fixing missing documentation, which is required so the next patch does not break the build - patch #5 aborts the build when documentation is missing for function arguments or the return value, except for those functions being part of the "ignored_functions" dictionary - patch #11 also adds an exception to syntax rules for the generated SHJS files - patch #12, #13 just add some indentation to make code blocks properly recognized This time, I did use make check and make syntax-check after every patch, so this should be OK. (fingers crossed) Claudio Bley (13): libvirt.h.in: add missing documentation for virConnectCloseFunc libvirt.h.in: fix documentation for virConnectDomainEventBlockJobCallback libvirt.h.in: add missing return doc for virEventRemoveHandleFunc libvirt.h.in: document virConnectDomainEventCallback's return value docs: abort when missing return or argument documentation docs: only generate function argument info for args with a description docs: use div, not table, for notices on opaque types docs: process code blocks similar to markdown docs: add class "description" to div's containing descriptions docs: define style of code blocks inside descriptions docs: syntax highlight code blocks using SHJS libvirt.c: indent code of virDomainGetMemoryParameters's documentation libvirt.c: add 2 spaces of indentation to example code cfg.mk | 2 +- docs/apibuild.py | 18 +++- docs/libvirt.css | 8 ++ docs/newapi.xsl | 209 +++++++++++++++++++++++++----------------- docs/page.xsl | 5 +- docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 + include/libvirt/libvirt.h.in | 16 +++- src/libvirt.c | 130 +++++++++++++------------- 10 files changed, 241 insertions(+), 153 deletions(-) create mode 100644 docs/sh_c.min.js create mode 100644 docs/sh_emacs.min.css create mode 100644 docs/sh_main.min.js -- 1.7.9.5

Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a634b37..b3cd490 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1398,6 +1398,15 @@ typedef enum { # endif } virConnectCloseReason; +/** + * virConnectCloseFunc: + * @conn: virConnect connection + * @reason: reason why the connection was closed (one of virConnectCloseReason) + * @opaque: opaque user data + * + * A callback function to be registered, and called when the connection + * is closed. + */ typedef void (*virConnectCloseFunc)(virConnectPtr conn, int reason, void *opaque); -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 9 +++++++++ 1 file changed, 9 insertions(+)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Wed, 30 Jan 2013 21:55:37 -0700, Eric Blake wrote:
[1 <text/plain; UTF-8 (quoted-printable)>] On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 9 +++++++++ 1 file changed, 9 insertions(+)
ACK.
Pushed. Thanks. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

In commit 3ac26e2645e6456389a918455213d7e3824f63f9 parameter "path" was renamed to "disk" but this change was not reflected in the documentation. Additionally, documentation of the "opaque" parameter was missing. Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index b3cd490..08eab47 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4359,9 +4359,10 @@ typedef enum { * virConnectDomainEventBlockJobCallback: * @conn: connection object * @dom: domain on which the event occurred - * @path: fully-qualified filename of the affected disk + * @disk: fully-qualified filename of the affected disk * @type: type of block job (virDomainBlockJobType) * @status: final status of the operation (virConnectDomainEventBlockJobStatus) + * @opaque: application specified data * * The callback signature to use when registering for an event of type * VIR_DOMAIN_EVENT_ID_BLOCK_JOB with virConnectDomainEventRegisterAny() -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
In commit 3ac26e2645e6456389a918455213d7e3824f63f9 parameter "path" was renamed to "disk" but this change was not reflected in the documentation.
Oops - that puts the blame on me :)
Additionally, documentation of the "opaque" parameter was missing.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Wed, 30 Jan 2013 21:57:01 -0700, Eric Blake wrote:
[1 <text/plain; UTF-8 (quoted-printable)>] On 01/30/2013 08:38 AM, Claudio Bley wrote:
In commit 3ac26e2645e6456389a918455213d7e3824f63f9 parameter "path" was renamed to "disk" but this change was not reflected in the documentation.
Oops - that puts the blame on me :)
Additionally, documentation of the "opaque" parameter was missing.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
ACK.
Pushed. Thanks. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 08eab47..4222fe1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3533,6 +3533,8 @@ typedef void (*virEventUpdateHandleFunc)(int watch, int event); * If a virEventHandleFreeFunc was supplied when the handle was * registered, it will be invoked some time during, or after this * function call, when it is safe to release the user data. + * + * Returns -1 if the file handle was not registered, 0 upon success */ typedef int (*virEventRemoveHandleFunc)(int watch); -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+)
ACK. I had to go hunting for where this callback was used, but this matches the documentation of util/virevent.c:virEventRemoveHandle() which uses this typedef as a callback.
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 08eab47..4222fe1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3533,6 +3533,8 @@ typedef void (*virEventUpdateHandleFunc)(int watch, int event); * If a virEventHandleFreeFunc was supplied when the handle was * registered, it will be invoked some time during, or after this * function call, when it is safe to release the user data. + * + * Returns -1 if the file handle was not registered, 0 upon success */ typedef int (*virEventRemoveHandleFunc)(int watch);
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Thu, 31 Jan 2013 05:52:18 -0700, Eric Blake wrote:
On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+)
ACK. I had to go hunting for where this callback was used, but this matches the documentation of util/virevent.c:virEventRemoveHandle() which uses this typedef as a callback.
Pushed, thanks. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 4222fe1..30762b1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3441,6 +3441,8 @@ typedef enum { * @opaque: opaque user data * * A callback function to be registered, and called when a domain event occurs + * + * Returns 0 (the return value is currently ignored) */ typedef int (*virConnectDomainEventCallback)(virConnectPtr conn, virDomainPtr dom, -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+)
Hmm, I wonder if we should at least log any situation where the user's callback returns non-zero, rather than flat-out ignoring it. But I suppose this works well enough for the moment; ACK.
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 4222fe1..30762b1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3441,6 +3441,8 @@ typedef enum { * @opaque: opaque user data * * A callback function to be registered, and called when a domain event occurs + * + * Returns 0 (the return value is currently ignored) */ typedef int (*virConnectDomainEventCallback)(virConnectPtr conn, virDomainPtr dom,
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Thu, 31 Jan 2013 10:21:25 -0700, Eric Blake wrote:
[1 <text/plain; UTF-8 (quoted-printable)>] On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- include/libvirt/libvirt.h.in | 2 ++ 1 file changed, 2 insertions(+)
Hmm, I wonder if we should at least log any situation where the user's callback returns non-zero, rather than flat-out ignoring it.
But I suppose this works well enough for the moment; ACK.
Pushed, thanks. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

When a function has no associated information to one of its arguments or its return type we report it and stop with an error. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/apibuild.py b/docs/apibuild.py index 91dabf8..6f2c751 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -1962,12 +1962,17 @@ class docBuilder: self.xref = {} self.index = {} self.basename = name + self.errors = 0 def warning(self, msg): global warnings warnings = warnings + 1 print msg + def error(self, msg): + self.errors += 1 + print >>sys.stderr, "Error:", msg + def indexString(self, id, str): if str == None: return @@ -2185,6 +2190,8 @@ class docBuilder: if ret[0] != None: if ret[0] == "void": output.write(" <return type='void'/>\n") + elif (ret[1] == None or ret[1] == '') and not ignored_functions.has_key(name): + self.error("Missing documentation for return of function `%s'" % name) else: output.write(" <return type='%s' info='%s'/>\n" % ( ret[0], escape(ret[1]))) @@ -2192,8 +2199,11 @@ class docBuilder: for param in params: if param[0] == 'void': continue - if param[2] == None: - output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) + if (param[2] == None or param[2] == ''): + if ignored_functions.has_key(name): + output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) + else: + self.error("Missing documentation for arg `%s' of function `%s'" % (param[1], name)) else: output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2]))) self.indexString(name, param[2]) @@ -2462,6 +2472,10 @@ class docBuilder: output.write("</api>\n") output.close() + if self.errors > 0: + print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation" % self.errors + sys.exit(3) + filename = "%s/%s-refs.xml" % (self.path, self.name) if not quiet: print "Saving XML Cross References %s" % (filename) -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
When a function has no associated information to one of its arguments or its return type we report it and stop with an error.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Thu, 31 Jan 2013 12:15:49 -0700, Eric Blake wrote:
On 01/30/2013 08:38 AM, Claudio Bley wrote:
When a function has no associated information to one of its arguments or its return type we report it and stop with an error.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
ACK.
Thanks, pushed. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

When function arguments or return values lack a description there's no use in generating a meaningless "ARG1: " stanza. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 0d32e55..fb95c44 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -533,9 +533,9 @@ </xsl:call-template> </div><xsl:text> </xsl:text> - <xsl:if test="arg | return/@info"> + <xsl:if test="arg[@info] | return/@info"> <dl class="variablelist"> - <xsl:for-each select="arg"> + <xsl:for-each select="arg[@info]"> <dt><xsl:value-of select="@name"/></dt> <dd> <xsl:call-template name="dumptext"> -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
When function arguments or return values lack a description there's no use in generating a meaningless "ARG1: " stanza.
Can you point to an example of an argument lacking a description? This is another case where I think we're better off fixing things to fail noisily so that we can fix our docs to be more complete, than we are to paper over it with this patch.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 0d32e55..fb95c44 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -533,9 +533,9 @@ </xsl:call-template> </div><xsl:text> </xsl:text> - <xsl:if test="arg | return/@info"> + <xsl:if test="arg[@info] | return/@info"> <dl class="variablelist"> - <xsl:for-each select="arg"> + <xsl:for-each select="arg[@info]"> <dt><xsl:value-of select="@name"/></dt> <dd> <xsl:call-template name="dumptext">
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Thu, 31 Jan 2013 13:41:10 -0700, Eric Blake wrote:
On 01/30/2013 08:38 AM, Claudio Bley wrote:
When function arguments or return values lack a description there's no use in generating a meaningless "ARG1: " stanza.
Can you point to an example of an argument lacking a description?
Have a look at e.g. #virEventUpdateHandle
This is another case where I think we're better off fixing things to fail noisily so that we can fix our docs to be more complete, than we are to paper over it with this patch.
The point is, we skip checking all functions contained in the "ignored_functions" dictionary in apibuild.py. We would have to do the same filtering inside the stylesheet also. But why bother? We never get to XSL processing when apibuild.py fails because of missing documentation. Not to mention the increased maintenance cost keeping those two files in sync. Note, however, that I have no deep understanding about what it means when a function ought to be "ignored" by apibuild.py. Should we skip this function from the generated HTML documentation perhaps? All I could see was that comment parsing and checking is a bit relaxed when a function is part of ignored_functions in mergeFunctionComment. That's why I chose to do the same. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

At Fri, 01 Feb 2013 13:48:45 +0100, Claudio Bley wrote:
At Thu, 31 Jan 2013 13:41:10 -0700, Eric Blake wrote:
On 01/30/2013 08:38 AM, Claudio Bley wrote:
When function arguments or return values lack a description there's no use in generating a meaningless "ARG1: " stanza.
Can you point to an example of an argument lacking a description?
Have a look at e.g. #virEventUpdateHandle
I just realized that this patch doesn't work anymore because I lost track of the original goal of not writing out empty info attributes for function arguments. (https://www.redhat.com/archives/libvir-list/2013-January/msg01537.html) Certainly because I figured it would not make sense anymore because we would bail out with an error if anything is missing. But then, I skipped the /ignored/ functions which re-introduced the empty info attributes in libvirt-api.xml. You need to squash this in prior before this has any effect. ---- >8 ---- diff --git a/docs/apibuild.py b/docs/apibuild.py index e5cbbe8..60e3b4a 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -2190,8 +2190,11 @@ class docBuilder: if ret[0] != None: if ret[0] == "void": output.write(" <return type='void'/>\n") - elif (ret[1] == None or ret[1] == '') and not ignored_functions.has_key(name): - self.error("Missing documentation for return of function `%s'" % name) + elif (ret[1] == None or ret[1] == ''): + if ignored_functions.has_key(name): + output.write(" <return type='%s'/>\n" % ret[0]) + else: + self.error("Missing documentation for return of function `%s'" % name) else: output.write(" <return type='%s' info='%s'/>\n" % ( ret[0], escape(ret[1]))) @@ -2201,7 +2204,7 @@ class docBuilder: continue if (param[2] == None or param[2] == ''): if ignored_functions.has_key(name): - output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) + output.write(" <arg name='%s' type='%s'/>\n" % (param[1], param[0])) else: self.error("Missing documentation for arg `%s' of function `%s'" % (param[1], name)) else:

On 02/01/2013 05:48 AM, Claudio Bley wrote:
The point is, we skip checking all functions contained in the "ignored_functions" dictionary in apibuild.py.
We would have to do the same filtering inside the stylesheet also.
But why bother? We never get to XSL processing when apibuild.py fails because of missing documentation.
Not to mention the increased maintenance cost keeping those two files in sync.
Note, however, that I have no deep understanding about what it means when a function ought to be "ignored" by apibuild.py.
Should we skip this function from the generated HTML documentation perhaps?
Indeed, when you frame the question that way, it seems like the smartest thing is to omit all output during apibuild.py for any function in the ignored_functions list; then the XSL processing wouldn't have anything to process in the first place. Hmm, I think this points out a bigger problem. Looking at ignored_functions, I see it starts with: "virDomainMigrateFinish": "private function for migration", Tracking down that function, it exists in src/libvirt.c, but is NOT in libvirt.h.in (just libvirt_internal.h), and is only exported in libvirt_private.syms. So not documenting it is the right thing to do. On the other hand, virEventUpdateHandle is a public entry point since libvirt 0.9.3, and declared in libvirt.h.in, so it is a public entry point. Why then are we hiding the documentation for this function? I don't think it should be in the ignored_functions list. Or put another way, I think the point of the ignored_functions list is to let apibuild.py snarf in entire files that contain both public and private functions, and to omit ALL documentation for private functions. Probably what happened is that virEventUpdateHandle used to be internal-only until 0.9.3, but we never updated the documentation generation to match when we finally made it public. So, we may not need this patch after all; instead, we need a patch that fixes the list of ignored_functions to be accurate to what is really private, when snarfing in all files that contain documentation for public functions. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Fri, 01 Feb 2013 10:22:28 -0700, Eric Blake wrote:
On 02/01/2013 05:48 AM, Claudio Bley wrote:
The point is, we skip checking all functions contained in the "ignored_functions" dictionary in apibuild.py.
We would have to do the same filtering inside the stylesheet also.
But why bother? We never get to XSL processing when apibuild.py fails because of missing documentation.
Not to mention the increased maintenance cost keeping those two files in sync.
Note, however, that I have no deep understanding about what it means when a function ought to be "ignored" by apibuild.py.
Should we skip this function from the generated HTML documentation perhaps?
Indeed, when you frame the question that way, it seems like the smartest thing is to omit all output during apibuild.py for any function in the ignored_functions list; then the XSL processing wouldn't have anything to process in the first place.
Hmm, I think this points out a bigger problem. Looking at ignored_functions, I see it starts with:
"virDomainMigrateFinish": "private function for migration",
Tracking down that function, it exists in src/libvirt.c, but is NOT in libvirt.h.in (just libvirt_internal.h), and is only exported in libvirt_private.syms. So not documenting it is the right thing to do. On the other hand, virEventUpdateHandle is a public entry point since libvirt 0.9.3, and declared in libvirt.h.in, so it is a public entry point.
As you determined this easily by looking at which file a function is declared in, would it make sense to employ the same logic in apibuild.py when deciding which function is public or not? Say, all functions found in libvirt.h (or libvirt.h.in for that matter), plus virterror.h are public, everything else is not.
So, we may not need this patch after all; instead, we need a patch that fixes the list of ignored_functions to be accurate to what is really private, when snarfing in all files that contain documentation for public functions.
And another one which actually omits generating entries for /ignored/ functions in libvirt-api.xml et. al., right? But, apparently, there are no ignored functions in libvirt-api.xml (et. al.). Probably because of some refactoring which put those functions out of the way into internal headers... So, we could just as well ditch the ignored_functions dictionary in apibuild.py because it only confuses people than being of any help or use. -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

On 02/06/2013 09:13 AM, Claudio Bley wrote:
Note, however, that I have no deep understanding about what it means when a function ought to be "ignored" by apibuild.py.
Should we skip this function from the generated HTML documentation perhaps?
Indeed, when you frame the question that way, it seems like the smartest thing is to omit all output during apibuild.py for any function in the ignored_functions list; then the XSL processing wouldn't have anything to process in the first place.
Hmm, I think this points out a bigger problem. Looking at ignored_functions, I see it starts with:
"virDomainMigrateFinish": "private function for migration",
Tracking down that function, it exists in src/libvirt.c, but is NOT in libvirt.h.in (just libvirt_internal.h), and is only exported in libvirt_private.syms. So not documenting it is the right thing to do. On the other hand, virEventUpdateHandle is a public entry point since libvirt 0.9.3, and declared in libvirt.h.in, so it is a public entry point.
As you determined this easily by looking at which file a function is declared in, would it make sense to employ the same logic in apibuild.py when deciding which function is public or not?
I'm no python expert, but if you want to write a patch, it sounds reasonable. Anything in a .h[.in] file under include/libvirt is public, anything else is ignored when it comes to documenting public functionality.
Say, all functions found in libvirt.h (or libvirt.h.in for that matter), plus virterror.h are public, everything else is not.
Well, there's also libvirt-qemu.h and libvirt-lxc.h, but yes, that's the idea.
So, we may not need this patch after all; instead, we need a patch that fixes the list of ignored_functions to be accurate to what is really private, when snarfing in all files that contain documentation for public functions.
And another one which actually omits generating entries for /ignored/ functions in libvirt-api.xml et. al., right?
Correct. Again, I won't be the person writing it, but I don't mind reviewing (it will help me learn more python).
But, apparently, there are no ignored functions in libvirt-api.xml (et. al.). Probably because of some refactoring which put those functions out of the way into internal headers...
So, we could just as well ditch the ignored_functions dictionary in apibuild.py because it only confuses people than being of any help or use.
Sure, if it works.
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

It's simpler to render and it prevents wrapping the line too early because of the table spacing, border et cetera. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 1 + docs/newapi.xsl | 110 +++++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/docs/libvirt.css b/docs/libvirt.css index 5dc5d9b..8a00d12 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -447,6 +447,7 @@ table.data tbody td.n { letter-spacing: .3ex; font-weight: bolder; text-transform: uppercase; + margin-left: 2em; } .api .directive { diff --git a/docs/newapi.xsl b/docs/newapi.xsl index fb95c44..09395ea 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -213,14 +213,51 @@ <xsl:text> { </xsl:text> </pre> - <table> - <xsl:for-each select="field"> - <xsl:choose> - <xsl:when test='@type = "union"'> - <tr><td><span class="keyword">union</span> {</td></tr> - <tr> - <td><table> - <xsl:for-each select="union/field"> + <xsl:if test="field"> + <table> + <xsl:for-each select="field"> + <xsl:choose> + <xsl:when test='@type = "union"'> + <tr><td><span class="keyword">union</span> {</td></tr> + <tr> + <td><table> + <xsl:for-each select="union/field"> + <tr> + <td> + <span class="type"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@type"/> + </xsl:call-template> + </span> + </td> + <td><xsl:value-of select="@name"/></td> + <xsl:if test="@info != ''"> + <td> + <div class="comment"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@info"/> + </xsl:call-template> + </div> + </td> + </xsl:if> + </tr> + </xsl:for-each> + </table></td> + <td></td></tr> + <tr><td>}</td> + <td><xsl:value-of select="@name"/></td> + <xsl:if test="@info != ''"> + <td> + <div class="comment"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@info"/> + </xsl:call-template> + </div> + </td> + </xsl:if> + <td></td></tr> + </xsl:when> + <xsl:otherwise> <tr> <td> <span class="type"> @@ -234,59 +271,20 @@ <td> <div class="comment"> <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> + <xsl:with-param name="text" select="@info"/> </xsl:call-template> </div> </td> </xsl:if> </tr> - </xsl:for-each> - </table></td> - <td></td></tr> - <tr><td>}</td> - <td><xsl:value-of select="@name"/></td> - <xsl:if test="@info != ''"> - <td> - <div class="comment"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> - </xsl:call-template> - </div> - </td> - </xsl:if> - <td></td></tr> - </xsl:when> - <xsl:otherwise> - <tr> - <td> - <span class="type"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@type"/> - </xsl:call-template> - </span> - </td> - <td><xsl:value-of select="@name"/></td> - <xsl:if test="@info != ''"> - <td> - <div class="comment"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> - </xsl:call-template> - </div> - </td> - </xsl:if> - </tr> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - <xsl:if test="not(field)"> - <tr> - <td colspan="3"> - <span class="undisclosed">The content of this structure is not made public by the API</span> - </td> - </tr> - </xsl:if> - </table> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + </table> + </xsl:if> + <xsl:if test="not(field)"> + <div class="undisclosed">The content of this structure is not made public by the API</div> + </xsl:if> <pre> <xsl:text> } -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
It's simpler to render and it prevents wrapping the line too early because of the table spacing, border et cetera.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 1 + docs/newapi.xsl | 110 +++++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 56 deletions(-)
My ACK from v2 stands. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Thu, 31 Jan 2013 14:55:55 -0700, Eric Blake wrote:
On 01/30/2013 08:38 AM, Claudio Bley wrote:
It's simpler to render and it prevents wrapping the line too early because of the table spacing, border et cetera.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 1 + docs/newapi.xsl | 110 +++++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 56 deletions(-)
My ACK from v2 stands.
Thanks, pushed. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

Wrap pre-formatted example code in <pre> elements. This works similar to markdown code blocks. Every line indented with at least 2 spaces is considered a code block and gets wrapped in a <pre> tag. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 89 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 09395ea..b11ce9c 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -83,6 +83,60 @@ </xsl:for-each> </xsl:template> + + <!-- process blocks of text. blocks are separated by two consecutive line --> + <!-- breaks. --> + <!-- --> + <!-- blocks indented with at least 2 spaces are considered code blocks. --> + <!-- --> + <!-- consecutive code blocks are collapsed into a single code block. --> + <xsl:template name="formatblock"> + <xsl:param name="block"/> + <xsl:param name="rest"/> + + <xsl:variable name="multipleCodeBlocks" + select="starts-with($block, ' ') and starts-with($rest, ' ')"/> + + <xsl:choose> + <xsl:when test="$multipleCodeBlocks"> + <xsl:call-template name="formatblock"> + <xsl:with-param name="block"> + <xsl:choose> + <xsl:when test="contains($rest, ' ')"> + <xsl:value-of select="concat($block, ' ', + substring-before($rest, ' '))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat($block, ' ', $rest)" /> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + <xsl:with-param name="rest" select="substring-after($rest, ' ')"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="starts-with($block, ' ')"> + <pre class="code"><xsl:for-each select="str:tokenize($block, ' ')"> + <xsl:value-of select="substring(., 3)"/> + <xsl:if test="position() != last()"> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each></pre> + </xsl:when> + <xsl:otherwise> + <p> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="$block"/> + </xsl:call-template> + </p> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not($multipleCodeBlocks)"> + <xsl:call-template name="formattext"> + <xsl:with-param name="text" select="$rest"/> + </xsl:call-template> + </xsl:if> + </xsl:template> + <xsl:template name="formattext"> <xsl:param name="text" /> @@ -90,28 +144,19 @@ <xsl:variable name="head" select="substring-before($text, ' ')"/> <xsl:variable name="rest" select="substring-after($text, ' ')"/> - <xsl:choose> - <xsl:when test="$head"> - <p> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="$head"/> - </xsl:call-template> - </p> - </xsl:when> - <xsl:when test="not($rest)"> - <p> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="$text"/> - </xsl:call-template> - </p> - </xsl:when> - </xsl:choose> - - <xsl:if test="$rest"> - <xsl:call-template name="formattext"> - <xsl:with-param name="text" select="$rest"/> - </xsl:call-template> - </xsl:if> + <xsl:call-template name="formatblock"> + <xsl:with-param name="block"> + <xsl:choose> + <xsl:when test="contains($text, ' ')"> + <xsl:value-of select="$head"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$text"/> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + <xsl:with-param name="rest" select="$rest"/> + </xsl:call-template> </xsl:if> </xsl:template> -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Wrap pre-formatted example code in <pre> elements. This works similar to markdown code blocks.
Every line indented with at least 2 spaces is considered a code block and gets wrapped in a <pre> tag.
Please, put a reference to an affected API in the commit message itself. I shouldn't have to hunt back to your v2 posting to see that you mentioned #virStreamRecv as a working sample.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 89 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 22 deletions(-)
This ate the 'do' part of the 'done:' label line in the code; if you fix that later in the series, you should rearrange the patches to get that fixed first. What prevents us from silently chopping off other leading information on code samples? Can you turn it into an error and/or end the <code> markup on any line that does not have the two leading spaces? I do like the result, though, once we tweak the remaining issues. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index b11ce9c..29ed94f 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -342,7 +342,7 @@ <xsl:variable name="name" select="string(@name)"/> <h3><a name="{$name}"><code><xsl:value-of select="$name"/></code></a></h3> <pre class="api"><span class="directive">#define</span><xsl:text> </xsl:text><xsl:value-of select="$name"/></pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> @@ -494,7 +494,7 @@ <xsl:text>) </xsl:text> </pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> @@ -570,7 +570,7 @@ </xsl:for-each> <xsl:text>)</xsl:text> </pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/libvirt.css b/docs/libvirt.css index 8a00d12..c9e8beb 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -477,3 +477,10 @@ dl.variablelist > dt { dl.variablelist > dt:after { content: ": "; } + +div.description pre.code { + border: 1px dashed grey; + background-color: inherit; + padding: 5px 10px 5px 10px; + margin-left: 2.5em; +} -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 7 +++++++ 1 file changed, 7 insertions(+)
Possibly could be merged with 9/13. I'm not sure I found a visual difference in this patch; where am I supposed to be looking? Is it only <code> elements within a "description" <div> that that get the new format; and if so, could you mention an anchor name in the commit message that gets improved?
diff --git a/docs/libvirt.css b/docs/libvirt.css index 8a00d12..c9e8beb 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -477,3 +477,10 @@ dl.variablelist > dt { dl.variablelist > dt:after { content: ": "; } + +div.description pre.code { + border: 1px dashed grey; + background-color: inherit; + padding: 5px 10px 5px 10px; + margin-left: 2.5em; +}
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Add minimized CSS and Javascript files of SHJS (http://shjs.sourceforge.net/) required for highlighting C code. Call sh_highlightDocument() in onload event handler. Since the new files are generated by a minifier tool, exclude them from being checked by syntax-check for proper newlines at EOF. Signed-off-by: Claudio Bley <cbley@av-test.de> --- cfg.mk | 2 +- docs/newapi.xsl | 2 +- docs/page.xsl | 5 ++++- docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 ++++ 6 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/sh_c.min.js create mode 100644 docs/sh_emacs.min.css create mode 100644 docs/sh_main.min.js diff --git a/cfg.mk b/cfg.mk index 2dfde01..a87bba4 100644 --- a/cfg.mk +++ b/cfg.mk @@ -798,7 +798,7 @@ exclude_file_name_regexp--sc_prohibit_close = \ (\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c)$$) exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \ - (^tests/(qemuhelp|nodeinfo)data/|\.(gif|ico|png|diff)$$) + (^tests/(qemuhelp|nodeinfo)data/|^docs/sh_[^/]*\.min\.[^/.]*$$|\.(gif|ico|png|diff)$$) _src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon) exclude_file_name_regexp--sc_prohibit_fork_wrappers = \ diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 29ed94f..a975ba8 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -115,7 +115,7 @@ </xsl:call-template> </xsl:when> <xsl:when test="starts-with($block, ' ')"> - <pre class="code"><xsl:for-each select="str:tokenize($block, ' ')"> + <pre class="code sh_c"><xsl:for-each select="str:tokenize($block, ' ')"> <xsl:value-of select="substring(., 3)"/> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> diff --git a/docs/page.xsl b/docs/page.xsl index bc8ea2a..bf7c446 100644 --- a/docs/page.xsl +++ b/docs/page.xsl @@ -136,10 +136,13 @@ <head> <link rel="stylesheet" type="text/css" href="{$href_base}main.css"/> <link rel="SHORTCUT ICON" href="{$href_base}32favicon.png"/> + <script type="text/javascript" src="{$href_base}sh_main.min.js"/> + <script type="text/javascript" src="{$href_base}sh_c.min.js"/> + <link rel="stylesheet" type="text/css" href="{$href_base}sh_emacs.min.css"/> <title>libvirt: <xsl:value-of select="html/body/h1"/></title> <meta name="description" content="libvirt, virtualization, virtualization API"/> </head> - <body> + <body onload="sh_highlightDocument();"> <div id="header"> <div id="headerLogo"/> <div id="headerSearch"> diff --git a/docs/sh_c.min.js b/docs/sh_c.min.js new file mode 100644 index 0000000..fd91118 --- /dev/null +++ b/docs/sh_c.min.js @@ -0,0 +1 @@ +if(!this.sh_languages){this.sh_languages={}}sh_languages.c=[[[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/(\bstruct)([ \t]+)([A-Za-z0-9_]+)/g,["sh_keyword","sh_normal","sh_classname"],-1],[/^[ \t]*#(?:[ \t]*include)/g,"sh_preproc",10,1],[/^[ \t]*#(?:[ \t]*[A-Za-z0-9_]*)/g,"sh_preproc",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",13],[/'/g,"sh_string",14],[/\b(?:__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|break|case|catch|cdecl|const|continue|default|do|else|enum|extern|for|goto|if|pascal|register|return|sizeof|static|struct|switch|typedef|union|volatile|while)\b/g,"sh_keyword",-1],[/\b(?:bool|char|double|float|int|long|short|signed|unsigned|void|wchar_ t)\b/g,"sh_type",-1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g,"sh_function",-1],[/([A-Za-z](?:[^`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\s]|[_])*)((?:<.*>)?)(\s+(?=[*&]*[A-Za-z][^`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\s]*\s*[`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\[\]]+))/g,["sh_usertype","sh_usertype","sh_normal"],-1]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh _todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",5]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/$/g,null,-2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword" ,6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/$/g,null,-2],[/</g,"sh_string",11],[/"/g,"sh_string",12],[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9]],[[/$/g,null,-2],[/>/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/"/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]],[[/'/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]]]; \ No newline at end of file diff --git a/docs/sh_emacs.min.css b/docs/sh_emacs.min.css new file mode 100644 index 0000000..b7aed87 --- /dev/null +++ b/docs/sh_emacs.min.css @@ -0,0 +1 @@ +pre.sh_sourceCode{background-color:#fff;color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_keyword{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_type{color:#208920;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_string{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_regexp{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_specialchar{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_comment{color:#ac2020;font-weight:normal;font-style:italic;}pre.sh_sourceCode .sh_number{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_preproc{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_function{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_url{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_date{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode . sh_time{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_file{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_ip{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_name{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_variable{color:#00f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_oldfile{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_newfile{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_difflines{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_selector{color:#00f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_property{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_value{color:#bd8d8b;font-weight:normal;font-style:normal;} \ No newline at end of file diff --git a/docs/sh_main.min.js b/docs/sh_main.min.js new file mode 100644 index 0000000..31d1ba0 --- /dev/null +++ b/docs/sh_main.min.js @@ -0,0 +1,4 @@ +/* Copyright (C) 2007, 2008 gnombat@users.sourceforge.net */ +/* License: http://shjs.sourceforge.net/doc/gplv3.html */ + +if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;F<o.length;F++){for(var H=0;H<o[F].length;H++){var G=o[F][H][0];if(G.source==="$"){G.exec=sh_konquerorExec}}}o.konquered=true}}var N=document.createElement("a");var q=document.createElement("span");var A=[];var j=0;var n=[];var C=0;var k=null;var x=function(i,a){var p=i.length;if(p===0){return}if(!a){var Q=n.length;if(Q!==0){var r=n[Q-1];if(!r[3]){a=r[1]}}}if(k!==a){if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}}if(a){var P;i f(a==="sh_url"){P=N.cloneNode(false)}else{P=q.cloneNode(false)}P.className=a;A[j++]={node:P,pos:C}}}C+=p;k=a};var t=/\r\n|\r|\n/g;t.lastIndex=0;var d=B.length;while(C<d){var v=C;var l;var w;var h=t.exec(B);if(h===null){l=d;w=d}else{l=h.index;w=t.lastIndex}var g=B.substring(v,l);var M=[];for(;;){var I=C-v;var D;var y=n.length;if(y===0){D=0}else{D=n[y-1][2]}var O=o[D];var z=O.length;var m=M[D];if(!m){m=M[D]=[]}var E=null;var u=-1;for(var K=0;K<z;K++){var f;if(K<m.length&&(m[K]===null||I<=m[K].index)){f=m[K]}else{var c=O[K][0];c.lastIndex=I;f=c.exec(g);m[K]=f}if(f!==null&&(E===null||f.index<E.index)){E=f;u=K;if(f.index===I){break}}}if(E===null){x(g.substring(I),null);break}else{if(E.index>I){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L<J.length;L++){b=E[L+1];x(b,J[L])}}else{b=E[0];x(b,J)}switch(e[2]){case -1:break;case -2:n.pop();break;case -3:n.length=0;break;default:n.push(e);break}}}if(k){A[j++]={pos:C};if(k==="sh_url"){sh_s etHref(A,j,B)}k=null}C=w}return A}function sh_getClasses(d){var a=[];var b=d.className;if(b&&b.length>0){var e=b.split(" ");for(var c=0;c<e.length;c++){if(e[c].length>0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b<d.length;b++){if(a.toLowerCase()===d[b].toLowerCase()){return}}d.push(a);c.className=d.join(" ")}function sh_extractTagsFromNodeList(c,a){var f=c.length;for(var d=0;d<f;d++){var e=c.item(d);switch(e.nodeType){case 1:if(e.nodeName.toLowerCase()==="br"){var b;if(/MSIE/.test(navigator.userAgent)){b="\r"}else{b="\n"}a.text.push(b);a.pos++}else{a.tags.push({node:e.cloneNode(false),pos:a.pos});sh_extractTagsFromNodeList(e.childNodes,a);a.tags.push({pos:a.pos})}break;case 3:case 4:a.text.push(e.data);a.pos+=e.length;break}}}function sh_extractTags(c,b){var a={};a.text=[];a.tags=b;a.pos=0;sh_extractTagsFromNodeList(c.childNodes,a);return a.text.join("")}function sh_mergeTags(d,f){var a=d.length;if(a===0){return f}var c=f.length;if (c===0){return d}var i=[];var e=0;var b=0;while(e<a&&b<c){var h=d[e];var g=f[b];if(h.pos<=g.pos){i.push(h);e++}else{i.push(g);if(f[b+1].pos<=h.pos){b++;i.push(f[b]);b++}else{i.push({pos:h.pos});f[b]={node:g.node.cloneNode(false),pos:h.pos}}}}while(e<a){i.push(d[e]);e++}while(b<c){i.push(f[b]);b++}return i}function sh_insertTags(k,h){var g=document;var l=document.createDocumentFragment();var e=0;var d=k.length;var b=0;var j=h.length;var c=l;while(b<j||e<d){var i;var a;if(e<d){i=k[e];a=i.pos}else{a=j}if(a<=b){if(i.node){var f=i.node;c.appendChild(f);c=f}else{c=c.parentNode}e++}else{c.appendChild(g.createTextNode(h.substring(b,a)));b=a}}return l}function sh_highlightElement(d,g){sh_addClass(d,"sh_sourceCode");var c=[];var e=sh_extractTags(d,c);var f=sh_highlightString(e,g);var b=sh_mergeTags(c,f);var a=sh_insertTags(b,e);while(d.hasChildNodes()){d.removeChild(d.firstChild)}d.appendChild(a)}function sh_getXMLHttpRequest(){if(window.ActiveXObject){return new ActiveXObject("Msxml2 .XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}throw"No XMLHttpRequest implementation available"}function sh_load(language,element,prefix,suffix){if(language in sh_requests){sh_requests[language].push(element);return}sh_requests[language]=[element];var request=sh_getXMLHttpRequest();var url=prefix+"sh_"+language+suffix;request.open("GET",url,true);request.onreadystatechange=function(){if(request.readyState===4){try{if(!request.status||request.status===200){eval(request.responseText);var elements=sh_requests[language];for(var i=0;i<elements.length;i++){sh_highlightElement(elements[i],sh_languages[language])}}else{throw"HTTP error: status "+request.status}}finally{request=null}}};request.send(null)}function sh_highlightDocument(g,k){var b=document.getElementsByTagName("pre");for(var e=0;e<b.length;e++){var f=b.item(e);var a=sh_getClasses(f);for(var c=0;c<a.length;c++){var h=a[c].toLowerCase();if(h==="sh_sourcecode"){continue}if(h.substr(0,3)==="sh_"){va r d=h.substring(3);if(d in sh_languages){sh_highlightElement(f,sh_languages[d])}else{if(typeof(g)==="string"&&typeof(k)==="string"){sh_load(d,f,g,k)}else{throw'Found <pre> element with class="'+h+'", but no such language exists'}}break}}}}; \ No newline at end of file -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Add minimized CSS and Javascript files of SHJS (http://shjs.sourceforge.net/) required for highlighting C code.
Call sh_highlightDocument() in onload event handler.
Since the new files are generated by a minifier tool, exclude them from being checked by syntax-check for proper newlines at EOF.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- cfg.mk | 2 +- docs/newapi.xsl | 2 +- docs/page.xsl | 5 ++++- docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 ++++ 6 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/sh_c.min.js create mode 100644 docs/sh_emacs.min.css create mode 100644 docs/sh_main.min.js
I'm still not convinced whether to take these patches, but if we do, you are missing Makefile.am changes that ensure the new files are shipped in the tarball and installed as part of 'make install'. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

By indenting code inside of comments, it gets recognized as a code block when generating the HTML documentation. Signed-off-by: Claudio Bley <cbley@av-test.de> --- See #virDomainGetMemoryParameters in the generated HTML document src/libvirt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index f81a3de..d9c4b6b 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3880,14 +3880,14 @@ error: * * Here is a sample code snippet: * - * if ((virDomainGetMemoryParameters(dom, NULL, &nparams, 0) == 0) && - * (nparams != 0)) { - * if ((params = malloc(sizeof(*params) * nparams)) == NULL) - * goto error; - * memset(params, 0, sizeof(*params) * nparams); - * if (virDomainGetMemoryParameters(dom, params, &nparams, 0)) - * goto error; - * } + * if ((virDomainGetMemoryParameters(dom, NULL, &nparams, 0) == 0) && + * (nparams != 0)) { + * if ((params = malloc(sizeof(*params) * nparams)) == NULL) + * goto error; + * memset(params, 0, sizeof(*params) * nparams); + * if (virDomainGetMemoryParameters(dom, params, &nparams, 0)) + * goto error; + * } * * This function may require privileged access to the hypervisor. This function * expects the caller to allocate the @params. -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
By indenting code inside of comments, it gets recognized as a code block when generating the HTML documentation.
Signed-off-by: Claudio Bley <cbley@av-test.de> ---
See #virDomainGetMemoryParameters in the generated HTML document
Move this comment above the --- line, and then you'll have my ACK. You can push this patch now, even if we don't have the magic <code> handling in prereq patches in place yet. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Claudio Bley <cbley@av-test.de> --- src/libvirt.c | 114 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index d9c4b6b..e287a3d 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -15716,37 +15716,37 @@ virStreamRef(virStreamPtr stream) * An example using this with a hypothetical file upload * API looks like * - * virStreamPtr st = virStreamNew(conn, 0); - * int fd = open("demo.iso", O_RDONLY) + * virStreamPtr st = virStreamNew(conn, 0); + * int fd = open("demo.iso", O_RDONLY) * - * virConnectUploadFile(conn, "demo.iso", st); - * - * while (1) { - * char buf[1024]; - * int got = read(fd, buf, 1024); - * if (got < 0) { - * virStreamAbort(st); - * break; - * } - * if (got == 0) { - * virStreamFinish(st); - * break; - * } - * int offset = 0; - * while (offset < got) { - * int sent = virStreamSend(st, buf+offset, got-offset) - * if (sent < 0) { + * virConnectUploadFile(conn, "demo.iso", st); + * + * while (1) { + * char buf[1024]; + * int got = read(fd, buf, 1024); + * if (got < 0) { * virStreamAbort(st); - * goto done; + * break; * } - * offset += sent; - * } - * } - * if (virStreamFinish(st) < 0) - * ... report an error .... - * done: - * virStreamFree(st); - * close(fd); + * if (got == 0) { + * virStreamFinish(st); + * break; + * } + * int offset = 0; + * while (offset < got) { + * int sent = virStreamSend(st, buf+offset, got-offset) + * if (sent < 0) { + * virStreamAbort(st); + * goto done; + * } + * offset += sent; + * } + * } + * if (virStreamFinish(st) < 0) + * ... report an error .... + * done: + * virStreamFree(st); + * close(fd); * * Returns the number of bytes written, which may be less * than requested. @@ -15810,35 +15810,35 @@ error: * An example using this with a hypothetical file download * API looks like * - * virStreamPtr st = virStreamNew(conn, 0); - * int fd = open("demo.iso", O_WRONLY, 0600) - * - * virConnectDownloadFile(conn, "demo.iso", st); - * - * while (1) { - * char buf[1024]; - * int got = virStreamRecv(st, buf, 1024); - * if (got < 0) - * break; - * if (got == 0) { - * virStreamFinish(st); - * break; - * } - * int offset = 0; - * while (offset < got) { - * int sent = write(fd, buf+offset, got-offset) - * if (sent < 0) { - * virStreamAbort(st); - * goto done; - * } - * offset += sent; - * } - * } - * if (virStreamFinish(st) < 0) - * ... report an error .... - * done: - * virStreamFree(st); - * close(fd); + * virStreamPtr st = virStreamNew(conn, 0); + * int fd = open("demo.iso", O_WRONLY, 0600) + * + * virConnectDownloadFile(conn, "demo.iso", st); + * + * while (1) { + * char buf[1024]; + * int got = virStreamRecv(st, buf, 1024); + * if (got < 0) + * break; + * if (got == 0) { + * virStreamFinish(st); + * break; + * } + * int offset = 0; + * while (offset < got) { + * int sent = write(fd, buf+offset, got-offset) + * if (sent < 0) { + * virStreamAbort(st); + * goto done; + * } + * offset += sent; + * } + * } + * if (virStreamFinish(st) < 0) + * ... report an error .... + * done: + * virStreamFree(st); + * close(fd); * * * Returns the number of bytes read, which may be less -- 1.7.9.5

On 01/30/2013 08:38 AM, Claudio Bley wrote:
Signed-off-by: Claudio Bley <cbley@av-test.de> --- src/libvirt.c | 114 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 57 deletions(-)
ACK if you mention the #virStreamRef anchor name in the commit message. Can be pushed now, even if the <code> handling patch is not yet in. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Claudio Bley
-
Eric Blake