From 3eca0559384b6cfb5556df8814039e27d6ec3cf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Tue, 10 Feb 2009 19:53:51 +0100
Subject: [PATCH] * testsuite/sexp-conv-test: Updated testcases for improved
 handling of comments.

* tools/sexp-conv.c (sexp_convert_item): Use sexp_put_soft_newline
to terminate comments, and modify indentation for the case that a
list starts with a comment.

* tools/output.c (sexp_output_init): Initialize soft_newline.
(sexp_put_raw_char): Clear soft_newline.
(sexp_put_newline): Check and reset soft_newline.
(sexp_put_soft_newline): New function.

* tools/output.h (struct sexp_output): Removed union with single
element, and updated all users. New attribute soft_newline.

Rev: nettle/ChangeLog:1.31
Rev: nettle/testsuite/sexp-conv-test:1.3
Rev: nettle/tools/output.c:1.3
Rev: nettle/tools/output.h:1.3
Rev: nettle/tools/sexp-conv.c:1.4
---
 ChangeLog                | 20 ++++++++++++++++++
 testsuite/sexp-conv-test |  2 --
 tools/output.c           | 44 ++++++++++++++++++++++++++++------------
 tools/output.h           | 12 +++++++----
 tools/sexp-conv.c        | 23 +++++++++++++++------
 5 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6051a223..c4ae037c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2009-02-10  Niels M�ller  <nisse@lysator.liu.se>
+
+	* base16-meta.c (base16_encode_update_wrapper): Mark ctx argument
+	as UNUSED.
+
+	* testsuite/sexp-conv-test: Updated testcases for improved
+	handling of comments.
+
+	* tools/sexp-conv.c (sexp_convert_item): Use sexp_put_soft_newline
+	to terminate comments, and modify indentation for the case that a
+	list starts with a comment.
+
+	* tools/output.c (sexp_output_init): Initialize soft_newline.
+	(sexp_put_raw_char): Clear soft_newline.
+	(sexp_put_newline): Check and reset soft_newline.
+	(sexp_put_soft_newline): New function.
+
+	* tools/output.h (struct sexp_output): Removed union with single
+	element, and updated all users. New attribute soft_newline.
+
 2008-12-22  Niels M�ller  <nisse@lysator.liu.se>
 
 	* Makefile.in ($(des_headers)): Create files in $(srcdir).
diff --git a/testsuite/sexp-conv-test b/testsuite/sexp-conv-test
index eed19e5a..a3470ab2 100755
--- a/testsuite/sexp-conv-test
+++ b/testsuite/sexp-conv-test
@@ -91,11 +91,9 @@ test_advanced '(foo bar baz)' '(foo bar
      baz)' 
 test_advanced '; comment
 ()' '; comment
-
 ()' 
 test_advanced '(foo ; gazonk
 bar)' '(foo ; gazonk
-     
      bar)'
 
 test_advanced '(foo[bar]foo)' '(foo [bar]foo)'
diff --git a/tools/output.c b/tools/output.c
index 6110b874..d491d9a4 100644
--- a/tools/output.c
+++ b/tools/output.c
@@ -47,6 +47,7 @@ sexp_output_init(struct sexp_output *output, FILE *f,
   output->ctx = NULL;
   
   output->pos = 0;
+  output->soft_newline = 0;
 }
 
 void
@@ -61,24 +62,41 @@ sexp_output_hash_init(struct sexp_output *output,
 static void
 sexp_put_raw_char(struct sexp_output *output, uint8_t c)
 {
-  output->pos++;
   if (putc(c, output->f) < 0)
     die("Write failed: %s\n", strerror(errno));
+
+  output->pos++;
+  output->soft_newline = 0;
 }
 
-void 
+void
 sexp_put_newline(struct sexp_output *output,
 		 unsigned indent)
 {
-  unsigned i;
+  if (output->soft_newline)
+    output->soft_newline = 0;
+  else
+    {
+      unsigned i;
 
-  sexp_put_raw_char(output, '\n');
-  output->pos = 0;
+      sexp_put_raw_char(output, '\n');
+      output->pos = 0;
   
-  for(i = 0; i < indent; i++)
-    sexp_put_raw_char(output, ' ');
+      for(i = 0; i < indent; i++)
+	sexp_put_raw_char(output, ' ');
   
-  output->pos = indent;
+      output->pos = indent;
+    }
+}
+
+/* Put a newline, but only if it is followed by another newline,
+   collaps to one newline only. */
+void
+sexp_put_soft_newline(struct sexp_output *output,
+		      unsigned indent)
+{
+  sexp_put_newline(output, indent);
+  output->soft_newline = 1;
 }
 
 void
@@ -86,13 +104,13 @@ sexp_put_char(struct sexp_output *output, uint8_t c)
 {
   if (output->coding)
     {
-      /* Two is enough for both hex and base64. */
+      /* Two is enough for both base16 and base64. */
       uint8_t encoded[2];
       unsigned done;
 
       unsigned i;
-      
-      done = output->coding->encode_update(&output->state, encoded,
+
+      done = output->coding->encode_update(&output->base64, encoded,
 					   1, &c);
       assert(done <= sizeof(encoded));
       
@@ -149,7 +167,7 @@ sexp_put_code_start(struct sexp_output *output,
   output->coding_indent = output->pos;
   
   output->coding = coding;
-  output->coding->encode_init(&output->state);
+  output->coding->encode_init(&output->base64);
 }
 
 void
@@ -161,7 +179,7 @@ sexp_put_code_end(struct sexp_output *output)
 
   assert(output->coding);
 
-  done = output->coding->encode_final(&output->state, encoded);
+  done = output->coding->encode_final(&output->base64, encoded);
 
   assert(done <= sizeof(encoded));
   
diff --git a/tools/output.h b/tools/output.h
index 79f147a0..8ac52562 100644
--- a/tools/output.h
+++ b/tools/output.h
@@ -45,12 +45,12 @@ struct sexp_output
   const struct nettle_hash *hash;
   void *ctx;
   
-  union {
-    struct base64_decode_ctx base64;
-    /* NOTE: There's no context for hex encoding */
-  } state;
+  /* NOTE: There's no context for hex encoding, the state argument to
+     encode_update is ignored */
+  struct base64_decode_ctx base64;
   
   unsigned pos;
+  int soft_newline;
 };
 
 void
@@ -65,6 +65,10 @@ void
 sexp_put_newline(struct sexp_output *output,
 		 unsigned indent);
 
+void
+sexp_put_soft_newline(struct sexp_output *output,
+		      unsigned indent);
+
 void
 sexp_put_char(struct sexp_output *output, uint8_t c);
 
diff --git a/tools/sexp-conv.c b/tools/sexp-conv.c
index d6ebef03..4b08a9cd 100644
--- a/tools/sexp-conv.c
+++ b/tools/sexp-conv.c
@@ -110,13 +110,26 @@ sexp_convert_item(struct sexp_parser *parser,
 	      {
 		/* FIXME: Adapt pretty printing to handle a big first
 		 * element. */
-		if (item == 1)
+		switch (item)
 		  {
+		  case 0:
+		    if (token->type == SEXP_COMMENT)
+		      {
+			indent = output->pos;
+			/* Disable the indentation setup for next item */
+			item++;
+		      }
+		    break;
+		    
+		  case  1:
 		    sexp_put_char(output, ' ');
 		    indent = output->pos;
+		    break;
+
+		  default:
+		    sexp_put_newline(output, indent);
+		    break;
 		  }
-		else if (item > 1)
-		  sexp_put_newline(output, indent);
 	      }
 
 	    sexp_convert_item(parser, token, output, mode_out, indent);
@@ -141,9 +154,7 @@ sexp_convert_item(struct sexp_parser *parser,
       if (mode_out == SEXP_ADVANCED)
 	{
 	  sexp_put_data(output, token->string.size, token->string.contents);
-	  /* This newline is necessary only if the comment comes first
-	     in a list. It would be nice to supress extra newlines. */
-	  sexp_put_newline(output, indent);
+	  sexp_put_soft_newline(output, indent);
 	}
       break;
     default:
-- 
GitLab