Use STREQ rather than strcmp
[platform/upstream/coreutils.git] / src / fmt.c
1 /* GNU fmt -- simple text formatter.
2    Copyright (C) 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Written by Ross Paterson <rap@doc.ic.ac.uk>.  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <getopt.h>
24
25 /* Redefine.  Otherwise, systems (Unicos for one) with headers that define
26    it to be a type get syntax errors for the variable declaration below.  */
27 #define word unused_word_type
28
29 #include "system.h"
30 #include "error.h"
31 #include "xstrtol.h"
32
33 /* The following parameters represent the program's idea of what is
34    "best".  Adjust to taste, subject to the caveats given.  */
35
36 /* Default longest permitted line length (max_width).  */
37 #define WIDTH   75
38
39 /* Prefer lines to be LEEWAY % shorter than the maximum width, giving
40    room for optimization.  */
41 #define LEEWAY  7
42
43 /* The default secondary indent of tagged paragraph used for unindented
44    one-line paragraphs not preceded by any multi-line paragraphs.  */
45 #define DEF_INDENT 3
46
47 /* Costs and bonuses are expressed as the equivalent departure from the
48    optimal line length, multiplied by 10.  e.g. assigning something a
49    cost of 50 means that it is as bad as a line 5 characters too short
50    or too long.  The definition of SHORT_COST(n) should not be changed.
51    However, EQUIV(n) may need tuning.  */
52
53 typedef long COST;
54
55 #define MAXCOST (~(((unsigned long) 1) << (8 * sizeof (COST) -1)))
56
57 #define SQR(n)          ((n) * (n))
58 #define EQUIV(n)        SQR ((COST) (n))
59
60 /* Cost of a filled line n chars longer or shorter than best_width.  */
61 #define SHORT_COST(n)   EQUIV ((n) * 10)
62
63 /* Cost of the difference between adjacent filled lines.  */
64 #define RAGGED_COST(n)  (SHORT_COST (n) / 2)
65
66 /* Basic cost per line.  */
67 #define LINE_COST       EQUIV (70)
68
69 /* Cost of breaking a line after the first word of a sentence, where
70    the length of the word is N.  */
71 #define WIDOW_COST(n)   (EQUIV (200) / ((n) + 2))
72
73 /* Cost of breaking a line before the last word of a sentence, where
74    the length of the word is N.  */
75 #define ORPHAN_COST(n)  (EQUIV (150) / ((n) + 2))
76
77 /* Bonus for breaking a line at the end of a sentence.  */
78 #define SENTENCE_BONUS  EQUIV (50)
79
80 /* Cost of breaking a line after a period not marking end of a sentence.
81    With the definition of sentence we are using (borrowed from emacs, see
82    get_line()) such a break would then look like a sentence break.  Hence
83    we assign a very high cost -- it should be avoided unless things are
84    really bad.  */
85 #define NOBREAK_COST    EQUIV (600)
86
87 /* Bonus for breaking a line before open parenthesis.  */
88 #define PAREN_BONUS     EQUIV (40)
89
90 /* Bonus for breaking a line after other punctuation.  */
91 #define PUNCT_BONUS     EQUIV(40)
92
93 /* Credit for breaking a long paragraph one line later.  */
94 #define LINE_CREDIT     EQUIV(3)
95
96 /* Size of paragraph buffer, in words and characters.  Longer paragraphs
97    are handled neatly (cf. flush_paragraph()), so there's little to gain
98    by making these larger.  */
99 #define MAXWORDS        1000
100 #define MAXCHARS        5000
101
102 /* Extra ctype(3)-style macros.  */
103
104 #define isopen(c)       (strchr ("([`'\"", c) != NULL)
105 #define isclose(c)      (strchr (")]'\"", c) != NULL)
106 #define isperiod(c)     (strchr (".?!", c) != NULL)
107
108 /* Size of a tab stop, for expansion on input and re-introduction on
109    output.  */
110 #define TABWIDTH        8
111
112 /* Miscellaneous definitions.  */
113
114 typedef unsigned int bool;
115 #undef TRUE
116 #define TRUE    1
117 #undef FALSE
118 #define FALSE   0
119
120 /* Word descriptor structure.  */
121
122 typedef struct Word WORD;
123
124 struct Word
125   {
126
127     /* Static attributes determined during input.  */
128
129     const char *text;           /* the text of the word */
130     short length;               /* length of this word */
131     short space;                /* the size of the following space */
132     bool paren:1;               /* starts with open paren */
133     bool period:1;              /* ends in [.?!])* */
134     bool punct:1;               /* ends in punctuation */
135     bool final:1;               /* end of sentence */
136
137     /* The remaining fields are computed during the optimization.  */
138
139     short line_length;          /* length of the best line starting here */
140     COST best_cost;             /* cost of best paragraph starting here */
141     WORD *next_break;           /* break which achieves best_cost */
142   };
143
144 /* Forward declarations.  */
145
146 static void set_prefix PARAMS ((char *p));
147 static void fmt PARAMS ((FILE *f));
148 static bool get_paragraph PARAMS ((FILE *f));
149 static int get_line PARAMS ((FILE *f, int c));
150 static int get_prefix PARAMS ((FILE *f));
151 static int get_space PARAMS ((FILE *f, int c));
152 static int copy_rest PARAMS ((FILE *f, int c));
153 static bool same_para PARAMS ((int c));
154 static void flush_paragraph PARAMS ((void));
155 static void fmt_paragraph PARAMS ((void));
156 static void check_punctuation PARAMS ((WORD *w));
157 static COST base_cost PARAMS ((WORD *this));
158 static COST line_cost PARAMS ((WORD *next, int len));
159 static void put_paragraph PARAMS ((WORD *finish));
160 static void put_line PARAMS ((WORD *w, int indent));
161 static void put_word PARAMS ((WORD *w));
162 static void put_space PARAMS ((int space));
163
164 /* The name this program was run with.  */
165 const char *program_name;
166
167 /* If nonzero, display usage information and exit.  */
168 static int show_help = 0;
169
170 /* If nonzero, print the version on standard output and exit.  */
171 static int show_version = 0;
172
173 /* Option values.  */
174
175 /* If TRUE, first 2 lines may have different indent (default FALSE).  */
176 static bool crown;
177
178 /* If TRUE, first 2 lines _must_ have different indent (default FALSE).  */
179 static bool tagged;
180
181 /* If TRUE, each line is a paragraph on its own (default FALSE).  */
182 static bool split;
183
184 /* If TRUE, don't preserve inter-word spacing (default FALSE).  */
185 static bool uniform;
186
187 /* Prefix minus leading and trailing spaces (default "").  */
188 static const char *prefix;
189
190 /* User-supplied maximum line width (default WIDTH).  The only output
191    lines
192    longer than this will each comprise a single word.  */
193 static int max_width;
194
195 /* Values derived from the option values.  */
196
197 /* The length of prefix minus leading space.  */
198 static int prefix_full_length;
199
200 /* The length of the leading space trimmed from the prefix.  */
201 static int prefix_lead_space;
202
203 /* The length of prefix minus leading and trailing space.  */
204 static int prefix_length;
205
206 /* The preferred width of text lines, set to LEEWAY % less than max_width.  */
207 static int best_width;
208
209 /* Dynamic variables.  */
210
211 /* Start column of the character most recently read from the input file.  */
212 static int in_column;
213
214 /* Start column of the next character to be written to stdout.  */
215 static int out_column;
216
217 /* Space for the paragraph text -- longer paragraphs are handled neatly
218    (cf. flush_paragraph()).  */
219 static char parabuf[MAXCHARS];
220
221 /* A pointer into parabuf, indicating the first unused character position.  */
222 static char *wptr;
223
224 /* The words of a paragraph -- longer paragraphs are handled neatly
225    (cf. flush_paragraph()).  */
226 static WORD word[MAXWORDS];
227
228 /* A pointer into the above word array, indicating the first position
229    after the last complete word.  Sometimes it will point at an incomplete
230    word.  */
231 static WORD *word_limit;
232
233 /* If TRUE, current input file contains tab characters, and so tabs can be
234    used for white space on output.  */
235 static bool tabs;
236
237 /* Space before trimmed prefix on each line of the current paragraph.  */
238 static int prefix_indent;
239
240 /* Indentation of the first line of the current paragraph.  */
241 static int first_indent;
242
243 /* Indentation of other lines of the current paragraph */
244 static int other_indent;
245
246 /* To detect the end of a paragraph, we need to look ahead to the first
247    non-blank character after the prefix on the next line, or the first
248    character on the following line that failed to match the prefix.
249    We can reconstruct the lookahead from that character (next_char), its
250    position on the line (in_column) and the amount of space before the
251    prefix (next_prefix_indent).  See get_paragraph() and copy_rest().  */
252
253 /* The last character read from the input file.  */
254 static int next_char;
255
256 /* The space before the trimmed prefix (or part of it) on the next line
257    after the current paragraph.  */
258 static int next_prefix_indent;
259
260 /* If nonzero, the length of the last line output in the current
261    paragraph, used to charge for raggedness at the split point for long
262    paragraphs chosen by fmt_paragraph().  */
263 static int last_line_length;
264
265 static void
266 usage (int status)
267 {
268   if (status != 0)
269     fprintf (stderr, _("Try `%s --help' for more information.\n"),
270              program_name);
271   else
272     {
273       printf (_("Usage: %s [-DIGITS] [OPTION]... [FILE]...\n"), program_name);
274       fputs (_("\
275 Reformat each paragraph in the FILE(s), writing to standard output.\n\
276 If no FILE or if FILE is `-', read standard input.\n\
277 \n\
278 Mandatory arguments to long options are mandatory for short options too.\n\
279   -c, --crown-margin        preserve indentation of first two lines\n\
280   -p, --prefix=STRING       combine only lines having STRING as prefix\n\
281   -s, --split-only          split long lines, but do not refill\n\
282   -t, --tagged-paragraph    indentation of first line different from second\n\
283   -u, --uniform-spacing     one space between words, two after sentences\n\
284   -w, --width=NUMBER        maximum line width (default of 75 columns)\n\
285       --help                display this help and exit\n\
286       --version             output version information and exit\n\
287 \n\
288 In -wNUMBER, the letter `w' may be omitted.\n"),
289              stdout);
290       puts (_("\nReport bugs to <textutils-bugs@gnu.org>."));
291     }
292   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
293 }
294
295 /* Decode options and launch execution.  */
296
297 static const struct option long_options[] =
298 {
299   {"crown-margin", no_argument, NULL, 'c'},
300   {"help", no_argument, &show_help, 1},
301   {"prefix", required_argument, NULL, 'p'},
302   {"split-only", no_argument, NULL, 's'},
303   {"tagged-paragraph", no_argument, NULL, 't'},
304   {"uniform-spacing", no_argument, NULL, 'u'},
305   {"version", no_argument, &show_version, 1},
306   {"width", required_argument, NULL, 'w'},
307   {0, 0, 0, 0},
308 };
309
310 int
311 main (register int argc, register char **argv)
312 {
313   int optchar;
314
315   program_name = argv[0];
316   setlocale (LC_ALL, "");
317   bindtextdomain (PACKAGE, LOCALEDIR);
318   textdomain (PACKAGE);
319
320   crown = tagged = split = uniform = FALSE;
321   max_width = WIDTH;
322   prefix = "";
323   prefix_length = prefix_lead_space = prefix_full_length = 0;
324
325   if (argc > 1 && argv[1][0] == '-' && ISDIGIT (argv[1][1]))
326     {
327       max_width = 0;
328       /* Old option syntax; a dash followed by one or more digits.
329          Move past the number. */
330       for (++argv[1]; ISDIGIT (*argv[1]); ++argv[1])
331         {
332           /* FIXME: use strtol to detect overflow.  */
333           max_width = max_width * 10 + *argv[1] - '0';
334         }
335       /* Make the options we just parsed invisible to getopt. */
336       argv[1] = argv[0];
337       argv++;
338       argc--;
339     }
340
341   while ((optchar = getopt_long (argc, argv, "0123456789cstuw:p:",
342                                  long_options, NULL))
343          != -1)
344     switch (optchar)
345       {
346       default:
347         usage (1);
348
349       case 0:
350         break;
351
352       case 'c':
353         crown = TRUE;
354         break;
355
356       case 's':
357         split = TRUE;
358         break;
359
360       case 't':
361         tagged = TRUE;
362         break;
363
364       case 'u':
365         uniform = TRUE;
366         break;
367
368       case 'w':
369         {
370           long int tmp_long;
371           if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
372               || tmp_long <= 0 || tmp_long > INT_MAX)
373             error (EXIT_FAILURE, 0, _("invalid line number increment: `%s'"),
374                    optarg);
375           max_width = (int) tmp_long;
376         }
377         break;
378
379       case 'p':
380         set_prefix (optarg);
381         break;
382
383       }
384
385   if (show_version)
386     {
387       printf ("fmt (%s) %s\n", GNU_PACKAGE, VERSION);
388       exit (EXIT_SUCCESS);
389     }
390
391   if (show_help)
392     usage (0);
393
394   best_width = max_width * (2 * (100 - LEEWAY) + 1) / 200;
395
396   if (optind == argc)
397     fmt (stdin);
398   else
399     {
400       for (; optind < argc; optind++)
401         {
402           char *file = argv[optind];
403           if (STREQ (file, "-"))
404             fmt (stdin);
405           else
406             {
407               FILE *in_stream;
408               in_stream = fopen (file, "r");
409               if (in_stream != NULL)
410                 {
411                   fmt (in_stream);
412                   if (fclose (in_stream) == EOF)
413                     error (EXIT_FAILURE, errno, file);
414                 }
415               else
416                 error (0, errno, file);
417             }
418         }
419     }
420
421   if (ferror (stdout) || fclose (stdout) == EOF)
422     error (EXIT_FAILURE, errno, _("write error"));
423
424   exit (EXIT_SUCCESS);
425 }
426
427 /* Trim space from the front and back of the string P, yielding the prefix,
428    and record the lengths of the prefix and the space trimmed.  */
429
430 static void
431 set_prefix (register char *p)
432 {
433   register char *s;
434
435   prefix_lead_space = 0;
436   while (*p == ' ')
437     {
438       prefix_lead_space++;
439       p++;
440     }
441   prefix = p;
442   prefix_full_length = strlen (p);
443   s = p + prefix_full_length;
444   while (s > p && s[-1] == ' ')
445     s--;
446   *s = '\0';
447   prefix_length = s - p;
448 }
449
450 /* read file F and send formatted output to stdout.  */
451
452 static void
453 fmt (FILE *f)
454 {
455   tabs = FALSE;
456   other_indent = 0;
457   next_char = get_prefix (f);
458   while (get_paragraph (f))
459     {
460       fmt_paragraph ();
461       put_paragraph (word_limit);
462     }
463 }
464
465 /* Read a paragraph from input file F.  A paragraph consists of a
466    maximal number of non-blank (excluding any prefix) lines subject to:
467    * In split mode, a paragraph is a single non-blank line.
468    * In crown mode, the second and subsequent lines must have the
469    same indentation, but possibly different from the indent of the
470    first line.
471    * Tagged mode is similar, but the first and second lines must have
472    different indentations.
473    * Otherwise, all lines of a paragraph must have the same indent.
474    If a prefix is in effect, it must be present at the same indent for
475    each line in the paragraph.
476
477    Return FALSE if end-of-file was encountered before the start of a
478    paragraph, else TRUE.  */
479
480 static bool
481 get_paragraph (FILE *f)
482 {
483   register int c;
484
485   last_line_length = 0;
486   c = next_char;
487
488   /* Scan (and copy) blank lines, and lines not introduced by the prefix.  */
489
490   while (c == '\n' || c == EOF
491          || next_prefix_indent < prefix_lead_space
492          || in_column < next_prefix_indent + prefix_full_length)
493     {
494       c = copy_rest (f, c);
495       if (c == EOF)
496         {
497           next_char = EOF;
498           return FALSE;
499         }
500       putchar ('\n');
501       c = get_prefix (f);
502     }
503
504   /* Got a suitable first line for a paragraph.  */
505
506   prefix_indent = next_prefix_indent;
507   first_indent = in_column;
508   wptr = parabuf;
509   word_limit = word;
510   c = get_line (f, c);
511
512   /* Read rest of paragraph (unless split is specified).  */
513
514   if (split)
515     other_indent = first_indent;
516   else if (crown)
517     {
518       if (same_para (c))
519         {
520           other_indent = in_column;
521           do
522             {                   /* for each line till the end of the para */
523               c = get_line (f, c);
524             }
525           while (same_para (c) && in_column == other_indent);
526         }
527       else
528         other_indent = first_indent;
529     }
530   else if (tagged)
531     {
532       if (same_para (c) && in_column != first_indent)
533         {
534           other_indent = in_column;
535           do
536             {                   /* for each line till the end of the para */
537               c = get_line (f, c);
538             }
539           while (same_para (c) && in_column == other_indent);
540         }
541
542       /* Only one line: use the secondary indent from last time if it
543          splits, or 0 if there have been no multi-line paragraphs in the
544          input so far.  But if these rules make the two indents the same,
545          pick a new secondary indent.  */
546
547       else if (other_indent == first_indent)
548         other_indent = first_indent == 0 ? DEF_INDENT : 0;
549     }
550   else
551     {
552       other_indent = first_indent;
553       while (same_para (c) && in_column == other_indent)
554         c = get_line (f, c);
555     }
556   (word_limit - 1)->period = (word_limit - 1)->final = TRUE;
557   next_char = c;
558   return TRUE;
559 }
560
561 /* Copy to the output a line that failed to match the prefix, or that
562    was blank after the prefix.  In the former case, C is the character
563    that failed to match the prefix.  In the latter, C is \n or EOF.
564    Return the character (\n or EOF) ending the line.  */
565
566 static int
567 copy_rest (FILE *f, register int c)
568 {
569   register const char *s;
570
571   out_column = 0;
572   if (in_column > next_prefix_indent && c != '\n' && c != EOF)
573     {
574       put_space (next_prefix_indent);
575       for (s = prefix; out_column != in_column && *s; out_column++)
576         putchar (*s++);
577       put_space (in_column - out_column);
578     }
579   while (c != '\n' && c != EOF)
580     {
581       putchar (c);
582       c = getc (f);
583     }
584   return c;
585 }
586
587 /* Return TRUE if a line whose first non-blank character after the
588    prefix (if any) is C could belong to the current paragraph,
589    otherwise FALSE.  */
590
591 static bool
592 same_para (register int c)
593 {
594   return (next_prefix_indent == prefix_indent
595           && in_column >= next_prefix_indent + prefix_full_length
596           && c != '\n' && c != EOF);
597 }
598
599 /* Read a line from input file F, given first non-blank character C
600    after the prefix, and the following indent, and break it into words.
601    A word is a maximal non-empty string of non-white characters.  A word
602    ending in [.?!]["')\]]* and followed by end-of-line or at least two
603    spaces ends a sentence, as in emacs.
604
605    Return the first non-blank character of the next line.  */
606
607 static int
608 get_line (FILE *f, register int c)
609 {
610   int start;
611   register char *end_of_parabuf;
612   register WORD *end_of_word;
613
614   end_of_parabuf = &parabuf[MAXCHARS];
615   end_of_word = &word[MAXWORDS - 2];
616
617   do
618     {                           /* for each word in a line */
619
620       /* Scan word.  */
621
622       word_limit->text = wptr;
623       do
624         {
625           if (wptr == end_of_parabuf)
626             flush_paragraph ();
627           *wptr++ = c;
628           c = getc (f);
629         }
630       while (c != EOF && !ISSPACE (c));
631       in_column += word_limit->length = wptr - word_limit->text;
632       check_punctuation (word_limit);
633
634       /* Scan inter-word space.  */
635
636       start = in_column;
637       c = get_space (f, c);
638       word_limit->space = in_column - start;
639       word_limit->final = (c == EOF
640                            || (word_limit->period
641                                && (c == '\n' || word_limit->space > 1)));
642       if (c == '\n' || c == EOF || uniform)
643         word_limit->space = word_limit->final ? 2 : 1;
644       if (word_limit == end_of_word)
645         flush_paragraph ();
646       word_limit++;
647       if (c == EOF)
648         return EOF;
649     }
650   while (c != '\n');
651   return get_prefix (f);
652 }
653
654 /* Read a prefix from input file F.  Return either first non-matching
655    character, or first non-blank character after the prefix.  */
656
657 static int
658 get_prefix (FILE *f)
659 {
660   register int c;
661   register const char *p;
662
663   in_column = 0;
664   c = get_space (f, getc (f));
665   if (prefix_length == 0)
666     next_prefix_indent = prefix_lead_space < in_column ?
667       prefix_lead_space : in_column;
668   else
669     {
670       next_prefix_indent = in_column;
671       for (p = prefix; *p != '\0'; p++)
672         {
673           if (c != *p)
674             return c;
675           in_column++;
676           c = getc (f);
677         }
678       c = get_space (f, c);
679     }
680   return c;
681 }
682
683 /* Read blank characters from input file F, starting with C, and keeping
684    in_column up-to-date.  Return first non-blank character.  */
685
686 static int
687 get_space (FILE *f, register int c)
688 {
689   for (;;)
690     {
691       if (c == ' ')
692         in_column++;
693       else if (c == '\t')
694         {
695           tabs = TRUE;
696           in_column = (in_column / TABWIDTH + 1) * TABWIDTH;
697         }
698       else
699         return c;
700       c = getc (f);
701     }
702 }
703
704 /* Set extra fields in word W describing any attached punctuation.  */
705
706 static void
707 check_punctuation (register WORD *w)
708 {
709   register const char *start, *finish;
710
711   start = w->text;
712   finish = start + (w->length - 1);
713   w->paren = isopen (*start);
714   w->punct = ISPUNCT (*finish);
715   while (isclose (*finish) && finish > start)
716     finish--;
717   w->period = isperiod (*finish);
718 }
719
720 /* Flush part of the paragraph to make room.  This function is called on
721    hitting the limit on the number of words or characters.  */
722
723 static void
724 flush_paragraph (void)
725 {
726   WORD *split_point;
727   register WORD *w;
728   int shift;
729   COST best_break;
730
731   /* In the special case where it's all one word, just flush it.  */
732
733   if (word_limit == word)
734     {
735       printf ("%*s", wptr - parabuf, parabuf);
736       wptr = parabuf;
737       return;
738     }
739
740   /* Otherwise:
741      - format what you have so far as a paragraph,
742      - find a low-cost line break near the end,
743      - output to there,
744      - make that the start of the paragraph.  */
745
746   fmt_paragraph ();
747
748   /* Choose a good split point.  */
749
750   split_point = word_limit;
751   best_break = MAXCOST;
752   for (w = word->next_break; w != word_limit; w = w->next_break)
753     {
754       if (w->best_cost - w->next_break->best_cost < best_break)
755         {
756           split_point = w;
757           best_break = w->best_cost - w->next_break->best_cost;
758         }
759       if (best_break <= MAXCOST - LINE_CREDIT)
760         best_break += LINE_CREDIT;
761     }
762   put_paragraph (split_point);
763
764   /* Copy text of words down to start of parabuf -- we use memmove because
765      the source and target may overlap.  */
766
767   memmove (parabuf, split_point->text, (size_t) (wptr - split_point->text));
768   shift = split_point->text - parabuf;
769   wptr -= shift;
770
771   /* Adjust text pointers.  */
772
773   for (w = split_point; w <= word_limit; w++)
774     w->text -= shift;
775
776   /* Copy words from split_point down to word -- we use memmove because
777      the source and target may overlap.  */
778
779   memmove ((char *) word, (char *) split_point,
780          (word_limit - split_point + 1) * sizeof (WORD));
781   word_limit -= split_point - word;
782 }
783
784 /* Compute the optimal formatting for the whole paragraph by computing
785    and remembering the optimal formatting for each suffix from the empty
786    one to the whole paragraph.  */
787
788 static void
789 fmt_paragraph (void)
790 {
791   register WORD *start, *w;
792   register int len;
793   register COST wcost, best;
794   int saved_length;
795
796   word_limit->best_cost = 0;
797   saved_length = word_limit->length;
798   word_limit->length = max_width;       /* sentinel */
799
800   for (start = word_limit - 1; start >= word; start--)
801     {
802       best = MAXCOST;
803       len = start == word ? first_indent : other_indent;
804
805       /* At least one word, however long, in the line.  */
806
807       w = start;
808       len += w->length;
809       do
810         {
811           w++;
812
813           /* Consider breaking before w.  */
814
815           wcost = line_cost (w, len) + w->best_cost;
816           if (start == word && last_line_length > 0)
817             wcost += RAGGED_COST (len - last_line_length);
818           if (wcost < best)
819             {
820               best = wcost;
821               start->next_break = w;
822               start->line_length = len;
823             }
824           len += (w - 1)->space + w->length;    /* w > start >= word */
825         }
826       while (len < max_width);
827       start->best_cost = best + base_cost (start);
828     }
829
830   word_limit->length = saved_length;
831 }
832
833 /* Return the constant component of the cost of breaking before the
834    word THIS.  */
835
836 static COST
837 base_cost (register WORD *this)
838 {
839   register COST cost;
840
841   cost = LINE_COST;
842
843   if (this > word)
844     {
845       if ((this - 1)->period)
846         {
847           if ((this - 1)->final)
848             cost -= SENTENCE_BONUS;
849           else
850             cost += NOBREAK_COST;
851         }
852       else if ((this - 1)->punct)
853         cost -= PUNCT_BONUS;
854       else if (this > word + 1 && (this - 2)->final)
855         cost += WIDOW_COST ((this - 1)->length);
856     }
857
858   if (this->paren)
859     cost -= PAREN_BONUS;
860   else if (this->final)
861     cost += ORPHAN_COST (this->length);
862
863   return cost;
864 }
865
866 /* Return the component of the cost of breaking before word NEXT that
867    depends on LEN, the length of the line beginning there.  */
868
869 static COST
870 line_cost (register WORD *next, register int len)
871 {
872   register int n;
873   register COST cost;
874
875   if (next == word_limit)
876     return 0;
877   n = best_width - len;
878   cost = SHORT_COST (n);
879   if (next->next_break != word_limit)
880     {
881       n = len - next->line_length;
882       cost += RAGGED_COST (n);
883     }
884   return cost;
885 }
886
887 /* Output to stdout a paragraph from word up to (but not including)
888    FINISH, which must be in the next_break chain from word.  */
889
890 static void
891 put_paragraph (register WORD *finish)
892 {
893   register WORD *w;
894
895   put_line (word, first_indent);
896   for (w = word->next_break; w != finish; w = w->next_break)
897     put_line (w, other_indent);
898 }
899
900 /* Output to stdout the line beginning with word W, beginning in column
901    INDENT, including the prefix (if any).  */
902
903 static void
904 put_line (register WORD *w, int indent)
905 {
906   register WORD *endline;
907
908   out_column = 0;
909   put_space (prefix_indent);
910   fputs (prefix, stdout);
911   out_column += prefix_length;
912   put_space (indent - out_column);
913
914   endline = w->next_break - 1;
915   for (; w != endline; w++)
916     {
917       put_word (w);
918       put_space (w->space);
919     }
920   put_word (w);
921   last_line_length = out_column;
922   putchar ('\n');
923 }
924
925 /* Output to stdout the word W.  */
926
927 static void
928 put_word (register WORD *w)
929 {
930   register const char *s;
931   register int n;
932
933   s = w->text;
934   for (n = w->length; n != 0; n--)
935     putchar (*s++);
936   out_column += w->length;
937 }
938
939 /* Output to stdout SPACE spaces, or equivalent tabs.  */
940
941 static void
942 put_space (int space)
943 {
944   register int space_target, tab_target;
945
946   space_target = out_column + space;
947   if (tabs)
948     {
949       tab_target = space_target / TABWIDTH * TABWIDTH;
950       if (out_column + 1 < tab_target)
951         while (out_column < tab_target)
952           {
953             putchar ('\t');
954             out_column = (out_column / TABWIDTH + 1) * TABWIDTH;
955           }
956     }
957   while (out_column < space_target)
958     {
959       putchar (' ');
960       out_column++;
961     }
962 }