#include #include int main(int argc, char **argv) { /* Line number or count associated with operation. This is positive if measured from start of file, or negative if measured from end of file. */ int line; /* Current read position. */ int current_line = 1; char *buffer = NULL; /* Input buffer. */ int capacity = 0; /* Buffer capacity. */ int size = 0; /* Number of bytes read. */ int eof = 0; /* End of file. */ char *r, *w; /* General purpose pointers inside buffer. */ if( argc != 2 ) { #if !defined(HEAD) && !defined(TAIL) return printf("%s {line_number}\n", *argv); #else return printf("%s {line_count}\n", *argv); #endif } #ifdef HEAD line = abs(atoi(argv[1])); #elif defined(TAIL) line = -abs(atoi(argv[1])); #else line = atoi(argv[1]); #endif while( !eof ) { /* Extend input buffer. */ if( size == capacity ) { if( (buffer = (char*)realloc(buffer, capacity += 4096)) == NULL ) { fprintf(stderr, "Out of memory (need %d)\n", capacity); return 1; } } size += fread(buffer + size, 1, capacity - size, stdin); eof = size < capacity; if( line >= 0 ) { /* Scanning forward. */ for(r = w = buffer; r != buffer + size; r++) { #ifdef HEAD /* Copy bytes up to the end of the requested line number. */ if( current_line <= line ) *w++ = *r; #else /* Copy bytes, skipping over requested line number. */ if( current_line != line ) *w++ = *r; #endif if( *r == '\n' ) current_line++; } fwrite(buffer, w - buffer, 1, stdout); size = 0; } else { /* Scanning backward. */ } } return 0; }