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{ 11if(len) { 12if(line[len -1] =='\n') 13 len--; 14 15while(len) { 16unsigned char c = line[len -1]; 17if(!isspace(c)) 18break; 19 len--; 20} 21} 22return 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_tstripspace(char*buffer,size_t length,int skip_comments) 42{ 43int empties = -1; 44size_t i, j, len, newlen; 45char*eol; 46 47for(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 51if(skip_comments && len && buffer[i] =='#') { 52 newlen =0; 53continue; 54} 55 newlen =cleanup(buffer + i, len); 56 57/* Not just an empty line? */ 58if(newlen) { 59if(empties != -1) 60 buffer[j++] ='\n'; 61if(empties >0) 62 buffer[j++] ='\n'; 63 empties =0; 64memmove(buffer + j, buffer + i, newlen); 65continue; 66} 67if(empties <0) 68continue; 69 empties++; 70} 71 72return j; 73} 74 75intcmd_stripspace(int argc,const char**argv,const char*prefix) 76{ 77char*buffer; 78unsigned long size; 79 80 size =1024; 81 buffer =xmalloc(size); 82if(read_pipe(0, &buffer, &size)) 83die("could not read the input"); 84 85 size =stripspace(buffer, size,0); 86write_or_die(1, buffer, size); 87if(size) 88putc('\n', stdout); 89 90free(buffer); 91return0; 92}