| 806 | hitting the limit on the number of words or characters. */ |
| 807 | |
| 808 | static void |
| 809 | flush_paragraph (void) |
| 810 | { |
| 811 | WORD *split_point; |
| 812 | WORD *w; |
| 813 | int shift; |
| 814 | COST best_break; |
| 815 | |
| 816 | /* In the special case where it's all one word, just flush it. */ |
| 817 | |
| 818 | if (word_limit == word) |
| 819 | { |
| 820 | size_t to_write = wptr - parabuf; |
| 821 | if (fwrite (parabuf, 1, to_write, stdout) != to_write) |
| 822 | write_error (); |
| 823 | |
| 824 | wptr = parabuf; |
| 825 | return; |
| 826 | } |
| 827 | |
| 828 | /* Otherwise: |
| 829 | - format what you have so far as a paragraph, |
| 830 | - find a low-cost line break near the end, |
| 831 | - output to there, |
| 832 | - make that the start of the paragraph. */ |
| 833 | |
| 834 | fmt_paragraph (); |
| 835 | |
| 836 | /* Choose a good split point. */ |
| 837 | |
| 838 | split_point = word_limit; |
| 839 | best_break = MAXCOST; |
| 840 | for (w = word->next_break; w != word_limit; w = w->next_break) |
| 841 | { |
| 842 | if (w->best_cost - w->next_break->best_cost < best_break) |
| 843 | { |
| 844 | split_point = w; |
| 845 | best_break = w->best_cost - w->next_break->best_cost; |
| 846 | } |
| 847 | if (best_break <= MAXCOST - LINE_CREDIT) |
| 848 | best_break += LINE_CREDIT; |
| 849 | } |
| 850 | put_paragraph (split_point); |
| 851 | |
| 852 | /* Copy text of words down to start of parabuf -- we use memmove because |
| 853 | the source and target may overlap. */ |
| 854 | |
| 855 | memmove (parabuf, split_point->text, wptr - split_point->text); |
| 856 | shift = split_point->text - parabuf; |
| 857 | wptr -= shift; |
| 858 | |
| 859 | /* Adjust text pointers. */ |
| 860 | |
| 861 | for (w = split_point; w <= word_limit; w++) |
| 862 | w->text -= shift; |
| 863 | |
| 864 | /* Copy words from split_point down to word -- we use memmove because |
| 865 | the source and target may overlap. */ |
no test coverage detected