builtin-stripspace.con commit Now that cache.h needs strbuf.h, remove useless includes. (ba3ed09)
   1#include "builtin.h"
   2#include "cache.h"
   3
   4/*
   5 * Returns the length of a line, without trailing spaces.
   6 *
   7 * If the line ends with newline, it will be removed too.
   8 */
   9static size_t cleanup(char *line, size_t len)
  10{
  11        if (len) {
  12                if (line[len - 1] == '\n')
  13                        len--;
  14
  15                while (len) {
  16                        unsigned char c = line[len - 1];
  17                        if (!isspace(c))
  18                                break;
  19                        len--;
  20                }
  21        }
  22        return len;
  23}
  24
  25/*
  26 * Remove empty lines from the beginning and end
  27 * and also trailing spaces from every line.
  28 *
  29 * Note that the buffer will not be NUL-terminated.
  30 *
  31 * Turn multiple consecutive empty lines between paragraphs
  32 * into just one empty line.
  33 *
  34 * If the input has only empty lines and spaces,
  35 * no output will be produced.
  36 *
  37 * If last line has a newline at the end, it will be removed.
  38 *
  39 * Enable skip_comments to skip every line starting with "#".
  40 */
  41size_t stripspace(char *buffer, size_t length, int skip_comments)
  42{
  43        int empties = -1;
  44        size_t i, j, len, newlen;
  45        char *eol;
  46
  47        for (i = j = 0; i < length; i += len, j += newlen) {
  48                eol = memchr(buffer + i, '\n', length - i);
  49                len = eol ? eol - (buffer + i) + 1 : length - i;
  50
  51                if (skip_comments && len && buffer[i] == '#') {
  52                        newlen = 0;
  53                        continue;
  54                }
  55                newlen = cleanup(buffer + i, len);
  56
  57                /* Not just an empty line? */
  58                if (newlen) {
  59                        if (empties != -1)
  60                                buffer[j++] = '\n';
  61                        if (empties > 0)
  62                                buffer[j++] = '\n';
  63                        empties = 0;
  64                        memmove(buffer + j, buffer + i, newlen);
  65                        continue;
  66                }
  67                if (empties < 0)
  68                        continue;
  69                empties++;
  70        }
  71
  72        return j;
  73}
  74
  75int cmd_stripspace(int argc, const char **argv, const char *prefix)
  76{
  77        struct strbuf buf;
  78        int strip_comments = 0;
  79
  80        if (argc > 1 && (!strcmp(argv[1], "-s") ||
  81                                !strcmp(argv[1], "--strip-comments")))
  82                strip_comments = 1;
  83
  84        strbuf_init(&buf, 0);
  85        if (strbuf_read(&buf, 0, 1024) < 0)
  86                die("could not read the input");
  87
  88        strbuf_setlen(&buf, stripspace(buf.buf, buf.len, strip_comments));
  89        if (buf.len)
  90                strbuf_addch(&buf, '\n');
  91
  92        write_or_die(1, buf.buf, buf.len);
  93        strbuf_release(&buf);
  94        return 0;
  95}