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