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_tcleanup(char*line,size_t len) 10{ 11while(len) { 12unsigned char c = line[len -1]; 13if(!isspace(c)) 14break; 15 len--; 16} 17 18return len; 19} 20 21/* 22 * Remove empty lines from the beginning and end 23 * and also trailing spaces from every line. 24 * 25 * Note that the buffer will not be NUL-terminated. 26 * 27 * Turn multiple consecutive empty lines between paragraphs 28 * into just one empty line. 29 * 30 * If the input has only empty lines and spaces, 31 * no output will be produced. 32 * 33 * If last line does not have a newline at the end, one is added. 34 * 35 * Enable skip_comments to skip every line starting with "#". 36 */ 37voidstripspace(struct strbuf *sb,int skip_comments) 38{ 39int empties =0; 40size_t i, j, len, newlen; 41char*eol; 42 43/* We may have to add a newline. */ 44strbuf_grow(sb,1); 45 46for(i = j =0; i < sb->len; i += len, j += newlen) { 47 eol =memchr(sb->buf + i,'\n', sb->len - i); 48 len = eol ? eol - (sb->buf + i) +1: sb->len - i; 49 50if(skip_comments && len && sb->buf[i] =='#') { 51 newlen =0; 52continue; 53} 54 newlen =cleanup(sb->buf + i, len); 55 56/* Not just an empty line? */ 57if(newlen) { 58if(empties >0&& j >0) 59 sb->buf[j++] ='\n'; 60 empties =0; 61memmove(sb->buf + j, sb->buf + i, newlen); 62 sb->buf[newlen + j++] ='\n'; 63}else{ 64 empties++; 65} 66} 67 68strbuf_setlen(sb, j); 69} 70 71intcmd_stripspace(int argc,const char**argv,const char*prefix) 72{ 73struct strbuf buf; 74int strip_comments =0; 75 76if(argc >1&& (!strcmp(argv[1],"-s") || 77!strcmp(argv[1],"--strip-comments"))) 78 strip_comments =1; 79 80strbuf_init(&buf,0); 81if(strbuf_read(&buf,0,1024) <0) 82die("could not read the input"); 83 84stripspace(&buf, strip_comments); 85 86write_or_die(1, buf.buf, buf.len); 87strbuf_release(&buf); 88return0; 89}