#define _POSIX_C_SOURCE 200809L #include /* close, write, pipe */ #include /* errorno */ #include /* assert */ #include /* err, warn */ #include /* free */ #include /* strlen, memcmp */ /* Napište podprogram ‹longest_line›, který přečte veškerá data ze * zadaného popisovače, a nalezne v nich nejdelší řádek. Výsledkem * bude počet bajtů, které tomuto řádku v souboru předchází (tzn. * adresa řádku v souboru) a jeho délka (včetně znaku konce řádku). * Tyto hodnoty předá volajícímu ve výstupních parametrech. Je-li * nejdelších řádků víc, použije se první z nich. Není-li na vstupu * žádný řádek, jedná se o chybu. Návratová hodnota bude 0 v případě * úspěchu a -1 jinak. */ int longest_line( int fd, int *offset, int *length ); /* ┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄┄┄┄ následují testy ┄┄┄┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄ */ #include /* openat */ static void close_or_warn( int fd, const char *name ) { if ( close( fd ) == -1 ) warn( "closing %s", name ); } static void unlink_if_exists( const char *file ) { if ( unlink( file ) == -1 && errno != ENOENT ) err( 2, "unlink" ); } static int check( const char *input, int expect_off, int expect_len ) { const char *name = "zt.r2_long.txt"; unlink_if_exists( name ); int fd = openat( AT_FDCWD, name, O_CREAT | O_WRONLY, 0755 ); if ( fd == -1 ) err( 2, "creating %s", name ); if ( write( fd, input, strlen( input ) ) == -1 ) err( 2, "writing into %s", name ); close_or_warn( fd, name ); fd = open( name, O_RDONLY ); if ( fd == -1 ) err( 2, "opening %s for reading", name ); int actual_off, actual_len; int result = longest_line( fd, &actual_off, &actual_len ); close_or_warn( fd, name ); int rv; if ( expect_off >= 0 ) rv = actual_off == expect_off && actual_len == expect_len; else rv = result == -1; unlink_if_exists( name ); return rv; } int main() { assert( check( "hello\n", 0, 6 ) ); assert( check( "Lorem\nipsum\n", 0, 6 ) ); assert( check( "dolor\nsit\n", 0, 6 ) ); assert( check( "amet,\nconsectetur\nadipisc\n", 6, 12 ) ); assert( check( "elit\nSed et nisi\negestas\n", 5, 12 ) ); assert( check( "dapibus\nfelis\nquis, feugiat est.\n", 14, 19 ) ); assert( check( "\n", 0, 1 ) ); assert( check( "\n\n", 0, 1 ) ); assert( check( "", -1, -1 ) ); assert( check( "hello?", -1, 0 ) ); assert( check( "anybody\nthere?", 0, 8 ) ); const char *longish = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" "Sed et nisi egestas, dapibus felis quis, feugiat est.\n" "Phasellus pellentesque sem quam, " "ac ullamcorper erat pharetra id.\n" "Curabitur non suscipit sapien, nec mattis massa.\n" "Curabitur convallis vulputate nunc id rhoncus.\n" "Donec sit amet justo nulla.\n" "Sed posuere tincidunt lacus euismod faucibus.\n" "Pellentesque condimentum facilisis nibh, " "non rutrum turpis rhoncus vitae.\n" "Phasellus sodales tellus nec tincidunt blandit.\n"; assert( check( longish, 347, 74 ) ); return 0; }