| 833 | where lines longer than N_BYTES bytes occur. */ |
| 834 | |
| 835 | static void |
| 836 | line_bytes_split (intmax_t n_bytes, char *buf, idx_t bufsize) |
| 837 | { |
| 838 | ssize_t n_read; |
| 839 | intmax_t n_out = 0; /* for each split. */ |
| 840 | idx_t n_hold = 0; |
| 841 | char *hold = NULL; /* for lines > bufsize. */ |
| 842 | idx_t hold_size = 0; |
| 843 | bool split_line = false; /* Whether a \n was output in a split. */ |
| 844 | |
| 845 | do |
| 846 | { |
| 847 | n_read = read (STDIN_FILENO, buf, bufsize); |
| 848 | if (n_read < 0) |
| 849 | error (EXIT_FAILURE, errno, "%s", quotef (infile)); |
| 850 | idx_t n_left = n_read; |
| 851 | char *sob = buf; |
| 852 | while (n_left) |
| 853 | { |
| 854 | idx_t split_rest = 0; |
| 855 | char *eoc = NULL; |
| 856 | char *eol; |
| 857 | |
| 858 | /* Determine End Of Chunk and/or End of Line, |
| 859 | which are used below to select what to write or buffer. */ |
| 860 | if (n_bytes - n_out - n_hold <= n_left) |
| 861 | { |
| 862 | /* Have enough for split. */ |
| 863 | split_rest = n_bytes - n_out - n_hold; |
| 864 | eoc = sob + split_rest - 1; |
| 865 | eol = memrchr (sob, eolchar, split_rest); |
| 866 | } |
| 867 | else |
| 868 | eol = memrchr (sob, eolchar, n_left); |
| 869 | |
| 870 | /* Output hold space if possible. */ |
| 871 | if (n_hold && !(!eol && n_out)) |
| 872 | { |
| 873 | cwrite (n_out == 0, hold, n_hold); |
| 874 | n_out += n_hold; |
| 875 | n_hold = 0; |
| 876 | } |
| 877 | |
| 878 | /* Output to eol if present. */ |
| 879 | if (eol) |
| 880 | { |
| 881 | split_line = true; |
| 882 | idx_t n_write = eol - sob + 1; |
| 883 | cwrite (n_out == 0, sob, n_write); |
| 884 | n_out += n_write; |
| 885 | n_left -= n_write; |
| 886 | sob += n_write; |
| 887 | if (eoc) |
| 888 | split_rest -= n_write; |
| 889 | } |
| 890 | |
| 891 | /* Output to eoc or eob if possible. */ |
| 892 | if (n_left && !split_line) |