All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carlos Rica <jasampler@gmail.com>
To: git@vger.kernel.org, "Junio C Hamano" <gitster@pobox.com>,
	"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Kristian Høgsberg" <krh@redhat.com>
Subject: [PATCH 1/2] Function stripspace now gets a buffer instead file descriptors.
Date: Wed, 11 Jul 2007 20:50:34 +0200	[thread overview]
Message-ID: <4695267A.7080202@gmail.com> (raw)

An implementation easier to call from builtins. It is designed
to be used from the upcoming builtin-tag.c and builtin-commit.c,
because both need to remove unwanted spaces from messages.

Signed-off-by: Carlos Rica <jasampler@gmail.com>
---

  This new implementation is a response to some Junio's comments
  on the version of builtin-tag.c which Kristian released:
  http://article.gmane.org/gmane.comp.version-control.git/49601

  The aim on not making this function internal yet
  is to be able to test it easily using the extensive
  test suite designed for git-stripspace. Later,
  this function could be in the file named "editor.c",
  along with the "launch_editor" function called when the
  program asks the user for a message not given from
  command-line.

 builtin-stripspace.c |   61 ++++++++++++++++++++++++++++++-------------------
 builtin.h            |    2 +-
 2 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index d8358e2..949b640 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -2,12 +2,11 @@
 #include "cache.h"

 /*
- * Remove trailing spaces from a line.
+ * Returns the length of a line removing trailing spaces.
  *
  * If the line ends with newline, it will be removed too.
- * Returns the new length of the string.
  */
-static int cleanup(char *line, int len)
+static size_t cleanup(char *line, size_t len)
 {
 	if (len) {
 		if (line[len - 1] == '\n')
@@ -19,7 +18,6 @@ static int cleanup(char *line, int len)
 				break;
 			len--;
 		}
-		line[len] = 0;
 	}
 	return len;
 }
@@ -28,52 +26,67 @@ static int cleanup(char *line, int len)
  * Remove empty lines from the beginning and end
  * and also trailing spaces from every line.
  *
+ * Note that the buffer will not be null-terminated.
+ *
  * Turn multiple consecutive empty lines between paragraphs
  * into just one empty line.
  *
  * If the input has only empty lines and spaces,
  * no output will be produced.
  *
+ * If last line has a newline at the end, it will be removed.
+ *
  * Enable skip_comments to skip every line starting with "#".
  */
-void stripspace(FILE *in, FILE *out, int skip_comments)
+size_t stripspace(char *buffer, size_t length, int skip_comments)
 {
 	int empties = -1;
-	int alloc = 1024;
-	char *line = xmalloc(alloc);
+	size_t i, j, len, newlen;
+	char *eol;

-	while (fgets(line, alloc, in)) {
-		int len = strlen(line);
+	for (i = j = 0; i < length; i += len, j += newlen) {
+		eol = memchr(buffer + i, '\n', length - i);
+		len = eol ? eol - (buffer + i) + 1 : length - i;

-		while (len == alloc - 1 && line[len - 1] != '\n') {
-			alloc = alloc_nr(alloc);
-			line = xrealloc(line, alloc);
-			fgets(line + len, alloc - len, in);
-			len += strlen(line + len);
-		}
-
-		if (skip_comments && line[0] == '#')
+		if (skip_comments && len && buffer[i] == '#') {
+			newlen = 0;
 			continue;
-		len = cleanup(line, len);
+		}
+		newlen = cleanup(buffer + i, len);

 		/* Not just an empty line? */
-		if (len) {
+		if (newlen) {
+			if (empties != -1)
+				buffer[j++] = '\n';
 			if (empties > 0)
-				fputc('\n', out);
+				buffer[j++] = '\n';
 			empties = 0;
-			fputs(line, out);
-			fputc('\n', out);
+			memmove(buffer + j, buffer + i, newlen);
 			continue;
 		}
 		if (empties < 0)
 			continue;
 		empties++;
 	}
-	free(line);
+
+	return j;
 }

 int cmd_stripspace(int argc, const char **argv, const char *prefix)
 {
-	stripspace(stdin, stdout, 0);
+	char *buffer;
+	unsigned long size;
+
+	size = 1024;
+	buffer = xmalloc(size);
+	if (read_pipe(0, &buffer, &size))
+		die("could not read the input");
+
+	size = stripspace(buffer, size, 0);
+	write_or_die(1, buffer, size);
+	if (size)
+		putc('\n', stdout);
+
+	free(buffer);
 	return 0;
 }
diff --git a/builtin.h b/builtin.h
index 661a92f..4cc228d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -7,7 +7,7 @@ extern const char git_version_string[];
 extern const char git_usage_string[];

 extern void help_unknown_cmd(const char *cmd);
-extern void stripspace(FILE *in, FILE *out, int skip_comments);
+extern size_t stripspace(char *buffer, size_t length, int skip_comments);
 extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
 extern void prune_packed_objects(int);

-- 
1.5.0

             reply	other threads:[~2007-07-11 18:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-11 18:50 Carlos Rica [this message]
2007-07-11 19:17 ` [PATCH 1/2] Function stripspace now gets a buffer instead file descriptors Johannes Schindelin
2007-07-11 22:24 ` Junio C Hamano
2007-07-11 23:20   ` Bill Lear
2007-07-11 23:41     ` Carlos Rica
2007-07-12  0:03       ` Junio C Hamano
2007-07-12  0:14   ` Carlos Rica

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4695267A.7080202@gmail.com \
    --to=jasampler@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=krh@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.