[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haiku-commits
Subject:    [haiku-commits] Change in buildtools[master]: jam: add an option to generate compile_commands.json
From:       Gerrit <review () review ! haiku-os ! org>
Date:       2020-09-22 18:32:16
Message-ID: gerrit.1600799536000.Ic5d44dc27baa2a2e4157324f6c5a228ab0366afe () review ! haiku-os ! org
[Download RAW message or body]

From Adrien Destugues <pulkomandy@gmail.com>:

Adrien Destugues has uploaded this change for review. ( https://review.haiku-os.org/c/buildtools/+/3260 )


Change subject: jam: add an option to generate compile_commands.json
......................................................................

jam: add an option to generate compile_commands.json

Based on Boost Jam patch: https://github.com/boostorg/build/pull/133
retrofitted to our version. Only the ruels whose name contains Cc or Cxx
are stored there. This can be improved if it's not good enough.

The commands are generated only as they are run. Unfortunately I think
with Jam there isn't really a way to do otherwise.
---
M jam/jam.c
M jam/jam.h
M jam/make1.c
3 files changed, 110 insertions(+), 2 deletions(-)



  git pull ssh://git.haiku-os.org:22/buildtools refs/changes/60/3260/1

diff --git a/jam/jam.c b/jam/jam.c
index 2bbf1ae..cf51d44 100644
--- a/jam/jam.c
+++ b/jam/jam.c
@@ -141,7 +141,8 @@
 # else
 	{ 0, 1 }, 		/* display actions  */
 # endif
-	0			/* output commands, not run them */
+	0,			/* output commands, not run them */
+	0			/* output compilation db here */
 } ;

 /* Symbols to be defined as true for use in Jambase */
@@ -182,7 +183,7 @@

 	argc--, argv++;

-	if( ( n = getoptions( argc, argv, "d:j:f:gs:t:ano:qv", optv ) ) < 0 )
+	if( ( n = getoptions( argc, argv, "d:j:f:gs:t:ano:cqv", optv ) ) < 0 )
 	{
 	    printf( "\nusage: jam [ options ] targets...\n\n" );

@@ -197,6 +198,7 @@
             printf( "-jx     Run up to x shell commands concurrently.\n" );
             printf( "-n      Don't actually execute the updating actions.\n" );
             printf( "-ox     Write the updating actions to file x.\n" );
+            printf( "-c      Output JSON compilation database to compile_commands.json.\n" );
             printf( "-q      Quit quickly as soon as a target fails.\n" );
 	    printf( "-sx=y   Set variable x=y, overriding environment.\n" );
             printf( "-tx     Rebuild x, even if it is up-to-date.\n" );
@@ -279,6 +281,17 @@
 	    }
 	}

+	/* If we're asked to produce a compilation database, open the file. */
+	if ( ( s = getoptval( optv, 'c', 0 ) ) )
+	{
+		if ( !( globs.comp_db = fopen( "compile_commands.json", "w" ) ) )
+		{
+			printf( "Failed to write to 'compile_commands.json'\n");
+			exit( EXITBAD );
+		}
+		fprintf(globs.comp_db, "[\n");
+	}
+
 	/* Set JAMDATE first */

 	{
@@ -439,5 +452,12 @@
 	if( globs.cmdout )
 	    fclose( globs.cmdout );

+	/* close compilation database output file */
+	if ( globs.comp_db )
+	{
+		fprintf(globs.comp_db, "]\n");
+		fclose( globs.comp_db );
+	}
+
 	return status ? EXITBAD : EXITOK;
 }
diff --git a/jam/jam.h b/jam/jam.h
index da3db48..6e509d5 100644
--- a/jam/jam.h
+++ b/jam/jam.h
@@ -500,6 +500,7 @@
 	int	quitquick;
 	int	newestfirst;		/* build newest sources first */
 	char	debug[DEBUG_MAX];
+	FILE	*comp_db;			/* output compilation db here */
 	FILE	*cmdout;		/* print cmds, not run them */
 } ;

diff --git a/jam/make1.c b/jam/make1.c
index ffb7831..888ea5c 100644
--- a/jam/make1.c
+++ b/jam/make1.c
@@ -73,6 +73,12 @@
 static SETTINGS *make1settings( LIST *vars );
 static void make1bind( TARGET *t, int warn );

+void out_compile_database(
+     char const * const action,
+     char const * const source,
+     char const * const command
+ );
+
 /* Ugly static - it's too hard to carry it through the callbacks. */

 static struct {
@@ -295,6 +301,17 @@
 	    if( globs.cmdout )
 		fprintf( globs.cmdout, "%s", cmd->buf );

+		if ( globs.comp_db != NULL )
+		{
+			const char* rule_name = cmd->rule->name;
+			const char* target_name = lol_get( (LOL *)&cmd->args, 0 )->string;
+			const char* source_name = NULL;
+			LIST* sources = lol_get( (LOL *)&cmd->args, 1);
+			if (sources != NULL)
+				source_name = lol_get((LOL *)&cmd->args, 1 )->string;
+			out_compile_database( rule_name, source_name, cmd->buf );
+		}
+
 	    if( globs.noexec )
 	    {
 		make1d( t, EXEC_CMD_OK );
@@ -671,3 +688,73 @@
 	t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
 	popsettings( t->settings );
 }
+
+
+static void out_json(char const* str, FILE* f)
+{
+     char const* escape_src = "\"\\\b\n\r\t";
+     char const* escape_subst[] = {
+         "\\\"", "\\\\", "\\b", "\\n", "\\r", "\\t"
+     };
+     char buffer[1024];
+     int i = 0;
+
+     /* trim leading whitespace */
+     while (*str != 0 && strchr(" \t\n\r\t", *str) != NULL)
+        ++str;
+
+     for (; *str != 0; ++str)
+     {
+         char const* ch;
+         char const* subst;
+         if (i >= sizeof(buffer) - 10)
+         {
+             buffer[i] = 0;
+             fputs(buffer, f);
+             i = 0;
+         }
+
+         /* skip non-printable characters */
+         if (*str < ' ' || *str > 127) continue;
+
+         ch = strchr(escape_src, *str);
+         if (ch == NULL)
+         {
+             buffer[i++] = *str;
+             continue;
+         }
+         subst = escape_subst[ch - escape_src];
+         strcpy(&buffer[i], subst);
+         i += strlen(subst);
+     }
+
+     buffer[i] = 0;
+     fputs(buffer, f);
+}
+
+
+void out_compile_database
+(
+     char const * const action,
+     char const * const source,
+     char const * const command
+)
+{
+     /* file format defined here:
+      * http://clang.llvm.org/docs/JSONCompilationDatabase.html
+      * we're not interested in link, mkdir, rm or any non-compile action
+      */
+     if (source
+        && (strstr(action, "Cc") != NULL || strstr(action, "Cxx") != NULL))
+     {
+         char buffer[256];
+         fputs("{ \"directory\": \"", globs.comp_db);
+         out_json(getcwd(buffer, sizeof(buffer)), globs.comp_db);
+         fputs("\", \"command\": \"", globs.comp_db);
+         out_json(command, globs.comp_db);
+         fputs("\", \"file\": \"", globs.comp_db);
+         out_json(source, globs.comp_db);
+         fputs("\" },\n", globs.comp_db);
+     }
+
+}

--
To view, visit https://review.haiku-os.org/c/buildtools/+/3260
To unsubscribe, or for help writing mail filters, visit https://review.haiku-os.org/settings

Gerrit-Project: buildtools
Gerrit-Branch: master
Gerrit-Change-Id: Ic5d44dc27baa2a2e4157324f6c5a228ab0366afe
Gerrit-Change-Number: 3260
Gerrit-PatchSet: 1
Gerrit-Owner: Adrien Destugues <pulkomandy@gmail.com>
Gerrit-MessageType: newchange

[Attachment #3 (text/html)]

<p>Adrien Destugues has uploaded this change for <strong>review</strong>.</p><p><a \
href="https://review.haiku-os.org/c/buildtools/+/3260">View Change</a></p><pre \
style="font-family: monospace,monospace; white-space: pre-wrap;">jam: add an option \
to generate compile_commands.json<br><br>Based on Boost Jam patch: \
https://github.com/boostorg/build/pull/133<br>retrofitted to our version. Only the \
ruels whose name contains Cc or Cxx<br>are stored there. This can be improved if \
it&#39;s not good enough.<br><br>The commands are generated only as they are run. \
Unfortunately I think<br>with Jam there isn&#39;t really a way to do \
otherwise.<br>---<br>M jam/jam.c<br>M jam/jam.h<br>M jam/make1.c<br>3 files changed, \
110 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: \
monospace,monospace; white-space: pre-wrap;">git pull \
ssh://git.haiku-os.org:22/buildtools refs/changes/60/3260/1</pre><pre \
style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git \
a/jam/jam.c b/jam/jam.c</span><br><span>index 2bbf1ae..cf51d44 \
100644</span><br><span>--- a/jam/jam.c</span><br><span>+++ \
b/jam/jam.c</span><br><span>@@ -141,7 +141,8 @@</span><br><span> # \
else</span><br><span> 	{ 0, 1 }, 		/* display actions  */</span><br><span> # \
endif</span><br><span style="color: hsl(0, 100%, 40%);">-	0			/* output commands, not \
run them */</span><br><span style="color: hsl(120, 100%, 40%);">+	0,			/* output \
commands, not run them */</span><br><span style="color: hsl(120, 100%, \
40%);">+	0			/* output compilation db here */</span><br><span> } ;</span><br><span> \
</span><br><span> /* Symbols to be defined as true for use in Jambase \
*/</span><br><span>@@ -182,7 +183,7 @@</span><br><span> </span><br><span> 	argc--, \
argv++;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-	if( ( n \
= getoptions( argc, argv, &quot;d:j:f:gs:t:ano:qv&quot;, optv ) ) &lt; 0 \
)</span><br><span style="color: hsl(120, 100%, 40%);">+	if( ( n = getoptions( argc, \
argv, &quot;d:j:f:gs:t:ano:cqv&quot;, optv ) ) &lt; 0 )</span><br><span> \
{</span><br><span> 	    printf( &quot;\nusage: jam [ options ] targets...\n\n&quot; \
);</span><br><span> </span><br><span>@@ -197,6 +198,7 @@</span><br><span>             \
printf( &quot;-jx     Run up to x shell commands concurrently.\n&quot; \
);</span><br><span>             printf( &quot;-n      Don&#39;t actually execute the \
updating actions.\n&quot; );</span><br><span>             printf( &quot;-ox     Write \
the updating actions to file x.\n&quot; );</span><br><span style="color: hsl(120, \
100%, 40%);">+            printf( &quot;-c      Output JSON compilation database to \
compile_commands.json.\n&quot; );</span><br><span>             printf( &quot;-q      \
Quit quickly as soon as a target fails.\n&quot; );</span><br><span> 	    printf( \
&quot;-sx=y   Set variable x=y, overriding environment.\n&quot; );</span><br><span>   \
printf( &quot;-tx     Rebuild x, even if it is up-to-date.\n&quot; \
);</span><br><span>@@ -279,6 +281,17 @@</span><br><span> 	    }</span><br><span> \
}</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+	/* If \
we&#39;re asked to produce a compilation database, open the file. */</span><br><span \
style="color: hsl(120, 100%, 40%);">+	if ( ( s = getoptval( optv, &#39;c&#39;, 0 ) ) \
)</span><br><span style="color: hsl(120, 100%, 40%);">+	{</span><br><span \
style="color: hsl(120, 100%, 40%);">+		if ( !( globs.comp_db = fopen( \
&quot;compile_commands.json&quot;, &quot;w&quot; ) ) )</span><br><span style="color: \
hsl(120, 100%, 40%);">+		{</span><br><span style="color: hsl(120, 100%, \
40%);">+			printf( &quot;Failed to write to \
&#39;compile_commands.json&#39;\n&quot;);</span><br><span style="color: hsl(120, \
100%, 40%);">+			exit( EXITBAD );</span><br><span style="color: hsl(120, 100%, \
40%);">+		}</span><br><span style="color: hsl(120, 100%, \
40%);">+		fprintf(globs.comp_db, &quot;[\n&quot;);</span><br><span style="color: \
hsl(120, 100%, 40%);">+	}</span><br><span style="color: hsl(120, 100%, \
40%);">+</span><br><span> 	/* Set JAMDATE first */</span><br><span> </span><br><span> \
{</span><br><span>@@ -439,5 +452,12 @@</span><br><span> 	if( globs.cmdout \
)</span><br><span> 	    fclose( globs.cmdout );</span><br><span> </span><br><span \
style="color: hsl(120, 100%, 40%);">+	/* close compilation database output file \
*/</span><br><span style="color: hsl(120, 100%, 40%);">+	if ( globs.comp_db \
)</span><br><span style="color: hsl(120, 100%, 40%);">+	{</span><br><span \
style="color: hsl(120, 100%, 40%);">+		fprintf(globs.comp_db, \
&quot;]\n&quot;);</span><br><span style="color: hsl(120, 100%, 40%);">+		fclose( \
globs.comp_db );</span><br><span style="color: hsl(120, 100%, \
40%);">+	}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> \
return status ? EXITBAD : EXITOK;</span><br><span> }</span><br><span>diff --git \
a/jam/jam.h b/jam/jam.h</span><br><span>index da3db48..6e509d5 \
100644</span><br><span>--- a/jam/jam.h</span><br><span>+++ \
b/jam/jam.h</span><br><span>@@ -500,6 +500,7 @@</span><br><span> \
int	quitquick;</span><br><span> 	int	newestfirst;		/* build newest sources first \
*/</span><br><span> 	char	debug[DEBUG_MAX];</span><br><span style="color: hsl(120, \
100%, 40%);">+	FILE	*comp_db;			/* output compilation db here */</span><br><span> \
FILE	*cmdout;		/* print cmds, not run them */</span><br><span> } ;</span><br><span> \
</span><br><span>diff --git a/jam/make1.c b/jam/make1.c</span><br><span>index \
ffb7831..888ea5c 100644</span><br><span>--- a/jam/make1.c</span><br><span>+++ \
b/jam/make1.c</span><br><span>@@ -73,6 +73,12 @@</span><br><span> static SETTINGS \
*make1settings( LIST *vars );</span><br><span> static void make1bind( TARGET *t, int \
warn );</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void \
out_compile_database(</span><br><span style="color: hsl(120, 100%, 40%);">+     char \
const * const action,</span><br><span style="color: hsl(120, 100%, 40%);">+     char \
const * const source,</span><br><span style="color: hsl(120, 100%, 40%);">+     char \
const * const command</span><br><span style="color: hsl(120, 100%, 40%);">+ \
);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Ugly \
static - it&#39;s too hard to carry it through the callbacks. */</span><br><span> \
</span><br><span> static struct {</span><br><span>@@ -295,6 +301,17 \
@@</span><br><span> 	    if( globs.cmdout )</span><br><span> 		fprintf( globs.cmdout, \
&quot;%s&quot;, cmd-&gt;buf );</span><br><span> </span><br><span style="color: \
hsl(120, 100%, 40%);">+		if ( globs.comp_db != NULL )</span><br><span style="color: \
hsl(120, 100%, 40%);">+		{</span><br><span style="color: hsl(120, 100%, \
40%);">+			const char* rule_name = cmd-&gt;rule-&gt;name;</span><br><span \
style="color: hsl(120, 100%, 40%);">+			const char* target_name = lol_get( (LOL \
*)&amp;cmd-&gt;args, 0 )-&gt;string;</span><br><span style="color: hsl(120, 100%, \
40%);">+			const char* source_name = NULL;</span><br><span style="color: hsl(120, \
100%, 40%);">+			LIST* sources = lol_get( (LOL *)&amp;cmd-&gt;args, \
1);</span><br><span style="color: hsl(120, 100%, 40%);">+			if (sources != \
NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+				source_name = \
lol_get((LOL *)&amp;cmd-&gt;args, 1 )-&gt;string;</span><br><span style="color: \
hsl(120, 100%, 40%);">+			out_compile_database( rule_name, source_name, cmd-&gt;buf \
);</span><br><span style="color: hsl(120, 100%, 40%);">+		}</span><br><span \
style="color: hsl(120, 100%, 40%);">+</span><br><span> 	    if( globs.noexec \
)</span><br><span> 	    {</span><br><span> 		make1d( t, EXEC_CMD_OK \
);</span><br><span>@@ -671,3 +688,73 @@</span><br><span> 	t-&gt;binding = t-&gt;time \
? T_BIND_EXISTS : T_BIND_MISSING;</span><br><span> 	popsettings( t-&gt;settings \
);</span><br><span> }</span><br><span style="color: hsl(120, 100%, \
40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span \
style="color: hsl(120, 100%, 40%);">+static void out_json(char const* str, FILE* \
f)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span \
style="color: hsl(120, 100%, 40%);">+     char const* escape_src = \
&quot;\&quot;\\\b\n\r\t&quot;;</span><br><span style="color: hsl(120, 100%, 40%);">+  \
char const* escape_subst[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  \
&quot;\\\&quot;&quot;, &quot;\\\\&quot;, &quot;\\b&quot;, &quot;\\n&quot;, \
&quot;\\r&quot;, &quot;\\t&quot;</span><br><span style="color: hsl(120, 100%, \
40%);">+     };</span><br><span style="color: hsl(120, 100%, 40%);">+     char \
buffer[1024];</span><br><span style="color: hsl(120, 100%, 40%);">+     int i = \
0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span \
style="color: hsl(120, 100%, 40%);">+     /* trim leading whitespace \
*/</span><br><span style="color: hsl(120, 100%, 40%);">+     while (*str != 0 \
&amp;&amp; strchr(&quot; \t\n\r\t&quot;, *str) != NULL)</span><br><span style="color: \
hsl(120, 100%, 40%);">+        ++str;</span><br><span style="color: hsl(120, 100%, \
40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (; *str != 0; \
++str)</span><br><span style="color: hsl(120, 100%, 40%);">+     {</span><br><span \
style="color: hsl(120, 100%, 40%);">+         char const* ch;</span><br><span \
style="color: hsl(120, 100%, 40%);">+         char const* subst;</span><br><span \
style="color: hsl(120, 100%, 40%);">+         if (i &gt;= sizeof(buffer) - \
10)</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span \
style="color: hsl(120, 100%, 40%);">+             buffer[i] = 0;</span><br><span \
style="color: hsl(120, 100%, 40%);">+             fputs(buffer, f);</span><br><span \
style="color: hsl(120, 100%, 40%);">+             i = 0;</span><br><span \
style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: \
hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         \
/* skip non-printable characters */</span><br><span style="color: hsl(120, 100%, \
40%);">+         if (*str &lt; &#39; &#39; || *str &gt; 127) \
continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span \
style="color: hsl(120, 100%, 40%);">+         ch = strchr(escape_src, \
*str);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (ch == \
NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span \
style="color: hsl(120, 100%, 40%);">+             buffer[i++] = *str;</span><br><span \
style="color: hsl(120, 100%, 40%);">+             continue;</span><br><span \
style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: \
hsl(120, 100%, 40%);">+         subst = escape_subst[ch - \
escape_src];</span><br><span style="color: hsl(120, 100%, 40%);">+         \
strcpy(&amp;buffer[i], subst);</span><br><span style="color: hsl(120, 100%, 40%);">+  \
i += strlen(subst);</span><br><span style="color: hsl(120, 100%, 40%);">+     \
}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: \
hsl(120, 100%, 40%);">+     buffer[i] = 0;</span><br><span style="color: hsl(120, \
100%, 40%);">+     fputs(buffer, f);</span><br><span style="color: hsl(120, 100%, \
40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span \
style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, \
40%);">+void out_compile_database</span><br><span style="color: hsl(120, 100%, \
40%);">+(</span><br><span style="color: hsl(120, 100%, 40%);">+     char const * \
const action,</span><br><span style="color: hsl(120, 100%, 40%);">+     char const * \
const source,</span><br><span style="color: hsl(120, 100%, 40%);">+     char const * \
const command</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span \
style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, \
40%);">+     /* file format defined here:</span><br><span style="color: hsl(120, \
100%, 40%);">+      * \
http://clang.llvm.org/docs/JSONCompilationDatabase.html</span><br><span style="color: \
hsl(120, 100%, 40%);">+      * we&#39;re not interested in link, mkdir, rm or any \
non-compile action</span><br><span style="color: hsl(120, 100%, 40%);">+      \
*/</span><br><span style="color: hsl(120, 100%, 40%);">+     if \
(source</span><br><span style="color: hsl(120, 100%, 40%);">+        &amp;&amp; \
(strstr(action, &quot;Cc&quot;) != NULL || strstr(action, &quot;Cxx&quot;) != \
NULL))</span><br><span style="color: hsl(120, 100%, 40%);">+     {</span><br><span \
style="color: hsl(120, 100%, 40%);">+         char buffer[256];</span><br><span \
style="color: hsl(120, 100%, 40%);">+         fputs(&quot;{ \&quot;directory\&quot;: \
\&quot;&quot;, globs.comp_db);</span><br><span style="color: hsl(120, 100%, 40%);">+  \
out_json(getcwd(buffer, sizeof(buffer)), globs.comp_db);</span><br><span \
style="color: hsl(120, 100%, 40%);">+         fputs(&quot;\&quot;, \
\&quot;command\&quot;: \&quot;&quot;, globs.comp_db);</span><br><span style="color: \
hsl(120, 100%, 40%);">+         out_json(command, globs.comp_db);</span><br><span \
style="color: hsl(120, 100%, 40%);">+         fputs(&quot;\&quot;, \
\&quot;file\&quot;: \&quot;&quot;, globs.comp_db);</span><br><span style="color: \
hsl(120, 100%, 40%);">+         out_json(source, globs.comp_db);</span><br><span \
style="color: hsl(120, 100%, 40%);">+         fputs(&quot;\&quot; },\n&quot;, \
globs.comp_db);</span><br><span style="color: hsl(120, 100%, 40%);">+     \
}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: \
hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a \
href="https://review.haiku-os.org/c/buildtools/+/3260">change 3260</a>. To \
unsubscribe, or for help writing mail filters, visit <a \
href="https://review.haiku-os.org/settings">settings</a>.</p><div itemscope \
itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" \
itemtype="http://schema.org/ViewAction"><link itemprop="url" \
href="about:invalid#zSoyz"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: buildtools </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: \
Ic5d44dc27baa2a2e4157324f6c5a228ab0366afe </div> <div style="display:none"> \
Gerrit-Change-Number: 3260 </div> <div style="display:none"> Gerrit-PatchSet: 1 \
</div> <div style="display:none"> Gerrit-Owner: Adrien Destugues \
&lt;pulkomandy@gmail.com&gt; </div> <div style="display:none"> Gerrit-MessageType: \
newchange </div>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic