Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / sort / sort.c
1 /* sort - sort lines of text (with all kinds of options).
2    Copyright (C) 1988, 1991, 1992, 1993, 1994, 1995 Free Software Foundation
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
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18    Written December 1988 by Mike Haertel.
19    The author may be reached (Email) at the address mike@gnu.ai.mit.edu,
20    or (US mail) as Mike Haertel c/o Free Software Foundation. */
21
22 /* $FreeBSD: src/gnu/usr.bin/sort/sort.c,v 1.15.2.4 2002/04/17 11:41:42 ache Exp $ */
23
24 #include <config.h>
25
26 /* Get isblank from GNU libc.  */
27 #define _GNU_SOURCE
28
29 #include <sys/types.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #ifdef __FreeBSD__
33 #include <locale.h>
34 #endif
35 #include "system.h"
36 #include "version.h"
37 #include "long-options.h"
38 #include "error.h"
39 #include "xstrtod.h"
40
41 #ifdef HAVE_LIMITS_H
42 #include <limits.h>
43 #else
44 #ifndef UCHAR_MAX
45 #define UCHAR_MAX 255
46 #endif
47 #endif
48 #ifndef STDC_HEADERS
49 char *malloc ();
50 char *realloc ();
51 void free ();
52 #endif
53
54 /* Undefine, to avoid warning about redefinition on some systems.  */
55 #undef min
56 #define min(a, b) ((a) < (b) ? (a) : (b))
57
58 #define UCHAR_LIM (UCHAR_MAX + 1)
59 #define UCHAR(c) ((unsigned char) (c))
60
61 #ifndef DEFAULT_TMPDIR
62 #define DEFAULT_TMPDIR "/tmp"
63 #endif
64
65 /* The kind of blanks for '-b' to skip in various options. */
66 enum blanktype { bl_start, bl_end, bl_both };
67
68 /* Lines are held in core as counted strings. */
69 struct line
70 {
71   char *text;                   /* Text of the line. */
72   int length;                   /* Length not including final newline. */
73   char *keybeg;                 /* Start of first key. */
74   char *keylim;                 /* Limit of first key. */
75 };
76
77 /* Arrays of lines. */
78 struct lines
79 {
80   struct line *lines;           /* Dynamically allocated array of lines. */
81   int used;                     /* Number of slots used. */
82   int alloc;                    /* Number of slots allocated. */
83   int limit;                    /* Max number of slots to allocate.  */
84 };
85
86 /* Input buffers. */
87 struct buffer
88 {
89   char *buf;                    /* Dynamically allocated buffer. */
90   int used;                     /* Number of bytes used. */
91   int alloc;                    /* Number of bytes allocated. */
92   int left;                     /* Number of bytes left after line parsing. */
93 };
94
95 struct keyfield
96 {
97   int sword;                    /* Zero-origin 'word' to start at. */
98   int schar;                    /* Additional characters to skip. */
99   int skipsblanks;              /* Skip leading white space at start. */
100   int eword;                    /* Zero-origin first word after field. */
101   int echar;                    /* Additional characters in field. */
102   int skipeblanks;              /* Skip trailing white space at finish. */
103   int *ignore;                  /* Boolean array of characters to ignore. */
104   char *translate;              /* Translation applied to characters. */
105   int numeric;                  /* Flag for numeric comparison.  Handle
106                                    strings of digits with optional decimal
107                                    point, but no exponential notation. */
108   int general_numeric;          /* Flag for general, numeric comparison.
109                                    Handle numbers in exponential notation. */
110   int month;                    /* Flag for comparison by month name. */
111   int reverse;                  /* Reverse the sense of comparison. */
112   struct keyfield *next;        /* Next keyfield to try. */
113 };
114
115 struct month
116 {
117   char *name;
118   int val;
119 };
120
121 /* The name this program was run with. */
122 char *program_name;
123
124 /* Table of digits. */
125 static int digits[UCHAR_LIM];
126
127 /* Table of white space. */
128 static int blanks[UCHAR_LIM];
129
130 /* Table of non-printing characters. */
131 static int nonprinting[UCHAR_LIM];
132
133 /* Table of non-dictionary characters (not letters, digits, or blanks). */
134 static int nondictionary[UCHAR_LIM];
135
136 /* Translation table folding lower case to upper. */
137 static char fold_toupper[UCHAR_LIM];
138
139 /* Table mapping 3-letter month names to integers.
140    Alphabetic order allows binary search. */
141 static struct month const monthtab[] =
142 {
143   {"APR", 4},
144   {"AUG", 8},
145   {"DEC", 12},
146   {"FEB", 2},
147   {"JAN", 1},
148   {"JUL", 7},
149   {"JUN", 6},
150   {"MAR", 3},
151   {"MAY", 5},
152   {"NOV", 11},
153   {"OCT", 10},
154   {"SEP", 9}
155 };
156
157 /* During the merge phase, the number of files to merge at once. */
158 #define NMERGE 16
159
160 /* Initial buffer size for in core sorting.  Will not grow unless a
161    line longer than this is seen. */
162 static int sortalloc = 512 * 1024;
163
164 /* Initial buffer size for in core merge buffers.  Bear in mind that
165    up to NMERGE * mergealloc bytes may be allocated for merge buffers. */
166 static int mergealloc =  16 * 1024;
167
168 /* Guess of average line length. */
169 static int linelength = 30;
170
171 /* Maximum number of elements for the array(s) of struct line's, in bytes.  */
172 #define LINEALLOC (256 * 1024)
173
174 /* Prefix for temporary file names. */
175 static char *temp_file_prefix;
176
177 /* Flag to reverse the order of all comparisons. */
178 static int reverse;
179
180 /* Flag for stable sort.  This turns off the last ditch bytewise
181    comparison of lines, and instead leaves lines in the same order
182    they were read if all keys compare equal.  */
183 static int stable;
184
185 /* Tab character separating fields.  If NUL, then fields are separated
186    by the empty string between a non-whitespace character and a whitespace
187    character. */
188 static char tab;
189
190 /* Flag to remove consecutive duplicate lines from the output.
191    Only the last of a sequence of equal lines will be output. */
192 static int unique;
193
194 /* Nonzero if any of the input files are the standard input. */
195 static int have_read_stdin;
196
197 /* Lists of key field comparisons to be tried. */
198 static struct keyfield keyhead;
199
200 #ifdef __FreeBSD__
201 static unsigned char decimal_point;
202
203 static int
204 COLLDIFF (int a, int b)
205 {
206         static char s[2][2];
207
208         if ((unsigned char)a == (unsigned char)b)
209                 return 0;
210         s[0][0] = a;
211         s[1][0] = b;
212         return strcoll(s[0], s[1]);
213 }
214
215 static int
216 collcmp(char *a, char *b, int mini)
217 {
218         char sa, sb;
219         int r;
220
221         sa = a[mini];
222         a[mini] = '\0';
223         sb = b[mini];
224         b[mini] = '\0';
225         r = strcoll(a, b);
226         a[mini] = sa;
227         b[mini] = sb;
228         return r;
229 }
230 #endif /* __FreeBSD__ */
231
232 static void
233 usage (int status)
234 {
235   if (status != 0)
236     fprintf (stderr, _("Try `%s --help' for more information.\n"),
237              program_name);
238   else
239     {
240       printf (_("\
241 Usage: %s [OPTION]... [FILE]...\n\
242 "),
243               program_name);
244       printf (_("\
245 Write sorted concatenation of all FILE(s) to standard output.\n\
246 \n\
247   +POS1 [-POS2]    start a key at POS1, end it before POS2\n\
248   -M               compare (unknown) < `JAN' < ... < `DEC', imply -b\n\
249   -T DIRECT        use DIRECT for temporary files, not $TMPDIR or %s\n\
250   -b               ignore leading blanks in sort fields or keys\n\
251   -c               check if given files already sorted, do not sort\n\
252   -d               consider only [a-zA-Z0-9 ] characters in keys\n\
253   -f               fold lower case to upper case characters in keys\n\
254   -g               compare according to general numerical value, imply -b\n\
255   -i               consider only [\\040-\\0176] characters in keys\n\
256   -k POS1[,POS2]   same as +POS1 [-POS2], but all positions counted from 1\n\
257   -m               merge already sorted files, do not sort\n\
258   -n               compare according to string numerical value, imply -b\n\
259   -o FILE          write result on FILE instead of standard output\n\
260   -r               reverse the result of comparisons\n\
261   -s               stabilize sort by disabling last resort comparison\n\
262   -t SEP           use SEParator instead of non- to whitespace transition\n\
263   -u               with -c, check for strict ordering\n\
264   -u               with -m, only output the first of an equal sequence\n\
265       --help       display this help and exit\n\
266       --version    output version information and exit\n\
267 \n\
268 POS is F[.C][OPTS], where F is the field number and C the character\n\
269 position in the field, both counted from zero.  OPTS is made up of one\n\
270 or more of Mbdfinr, this effectively disable global -Mbdfinr settings\n\
271 for that key.  If no key given, use the entire line as key.  With no\n\
272 FILE, or when FILE is -, read standard input.\n\
273 ")
274               , DEFAULT_TMPDIR);
275     }
276   exit (status);
277 }
278
279 /* The list of temporary files. */
280 static struct tempnode
281 {
282   char *name;
283   struct tempnode *next;
284 } temphead;
285
286 /* Clean up any remaining temporary files. */
287
288 static void
289 cleanup (void)
290 {
291   struct tempnode *node;
292
293   for (node = temphead.next; node; node = node->next)
294     unlink (node->name);
295 }
296
297 /* Allocate N bytes of memory dynamically, with error checking.  */
298
299 static char *
300 xmalloc (unsigned int n)
301 {
302   char *p;
303
304   p = malloc (n);
305   if (p == 0)
306     {
307       error (0, 0, _("virtual memory exhausted"));
308       cleanup ();
309       exit (2);
310     }
311   return p;
312 }
313
314 /* Change the size of an allocated block of memory P to N bytes,
315    with error checking.
316    If P is NULL, run xmalloc.
317    If N is 0, run free and return NULL.  */
318
319 static char *
320 xrealloc (char *p, unsigned int n)
321 {
322   if (p == 0)
323     return xmalloc (n);
324   if (n == 0)
325     {
326       free (p);
327       return 0;
328     }
329   p = realloc (p, n);
330   if (p == 0)
331     {
332       error (0, 0, _("virtual memory exhausted"));
333       cleanup ();
334       exit (2);
335     }
336   return p;
337 }
338
339 static FILE *
340 xtmpfopen (const char *file)
341 {
342   FILE *fp;
343   int fd;
344
345   fd = open (file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
346   if (fd < 0 || (fp = fdopen (fd, "w")) == NULL)
347     {
348       error (0, errno, "%s", file);
349       cleanup ();
350       exit (2);
351     }
352
353   return fp;
354 }
355
356 static FILE *
357 xfopen (const char *file, const char *how)
358 {
359   FILE *fp;
360
361   if (strcmp (file, "-") == 0)
362     {
363       fp = stdin;
364     }
365   else
366     {
367       if ((fp = fopen (file, how)) == NULL)
368         {
369           error (0, errno, "%s", file);
370           cleanup ();
371           exit (2);
372         }
373     }
374
375   if (fp == stdin)
376     have_read_stdin = 1;
377   return fp;
378 }
379
380 static void
381 xfclose (FILE *fp)
382 {
383   if (fp == stdin)
384     {
385       /* Allow reading stdin from tty more than once. */
386       if (feof (fp))
387         clearerr (fp);
388     }
389   else if (fp == stdout)
390     {
391       if (fflush (fp) != 0)
392         {
393           error (0, errno, _("flushing file"));
394           cleanup ();
395           exit (2);
396         }
397     }
398   else
399     {
400       if (fclose (fp) != 0)
401         {
402           error (0, errno, _("error closing file"));
403           cleanup ();
404           exit (2);
405         }
406     }
407 }
408
409 static void
410 xfwrite (const char *buf, int size, int nelem, FILE *fp)
411 {
412   if (fwrite (buf, size, nelem, fp) != nelem)
413     {
414       error (0, errno, _("write error"));
415       cleanup ();
416       exit (2);
417     }
418 }
419
420 /* Return a name for a temporary file. */
421
422 static char *
423 tempname (void)
424 {
425   int fd;
426   int len = strlen (temp_file_prefix);
427   char *name = xmalloc (len + 1 + sizeof ("sort") - 1 + 5 + 5 + 1);
428   struct tempnode *node;
429
430   node = (struct tempnode *) xmalloc (sizeof (struct tempnode));
431   sprintf (name,
432            "%s%ssortXXXXXX",
433            temp_file_prefix,
434            (len && temp_file_prefix[len - 1] != '/') ? "/" : "");
435
436   if ((fd = mkstemp(name)) == -1)
437     {
438       error (0, errno, _("mkstemp error"));
439       cleanup ();
440       exit (2);
441     }
442   close(fd);
443
444   node->name = name;
445   node->next = temphead.next;
446   temphead.next = node;
447   return name;
448 }
449
450 /* Search through the list of temporary files for NAME;
451    remove it if it is found on the list. */
452
453 static void
454 zaptemp (char *name)
455 {
456   struct tempnode *node, *temp;
457
458   for (node = &temphead; node->next; node = node->next)
459     if (!strcmp (name, node->next->name))
460       break;
461   if (node->next)
462     {
463       temp = node->next;
464       unlink (temp->name);
465       free (temp->name);
466       node->next = temp->next;
467       free ((char *) temp);
468     }
469 }
470
471 /* Initialize the character class tables. */
472
473 static void
474 inittables (void)
475 {
476   int i;
477
478   for (i = 0; i < UCHAR_LIM; ++i)
479     {
480       if (ISBLANK (i))
481         blanks[i] = 1;
482       if (ISDIGIT (i))
483         digits[i] = 1;
484       if (!ISPRINT (i))
485         nonprinting[i] = 1;
486       if (!ISALNUM (i) && !ISBLANK (i))
487         nondictionary[i] = 1;
488       if (ISLOWER (i))
489         fold_toupper[i] = toupper (i);
490       else
491         fold_toupper[i] = i;
492     }
493 }
494
495 /* Initialize BUF, allocating ALLOC bytes initially. */
496
497 static void
498 initbuf (struct buffer *buf, int alloc)
499 {
500   buf->alloc = alloc;
501   buf->buf = xmalloc (buf->alloc);
502   buf->used = buf->left = 0;
503 }
504
505 /* Fill BUF reading from FP, moving buf->left bytes from the end
506    of buf->buf to the beginning first.  If EOF is reached and the
507    file wasn't terminated by a newline, supply one.  Return a count
508    of bytes buffered. */
509
510 static int
511 fillbuf (struct buffer *buf, FILE *fp)
512 {
513   int cc;
514
515   memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left);
516   buf->used = buf->left;
517
518   while (!feof (fp) && (buf->used == 0 || !memchr (buf->buf, '\n', buf->used)))
519     {
520       if (buf->used == buf->alloc)
521         {
522           buf->alloc *= 2;
523           buf->buf = xrealloc (buf->buf, buf->alloc);
524         }
525       cc = fread (buf->buf + buf->used, 1, buf->alloc - buf->used, fp);
526       if (ferror (fp))
527         {
528           error (0, errno, _("read error"));
529           cleanup ();
530           exit (2);
531         }
532       buf->used += cc;
533     }
534
535   if (feof (fp) && buf->used && buf->buf[buf->used - 1] != '\n')
536     {
537       if (buf->used == buf->alloc)
538         {
539           buf->alloc *= 2;
540           buf->buf = xrealloc (buf->buf, buf->alloc);
541         }
542       buf->buf[buf->used++] = '\n';
543     }
544
545   return buf->used;
546 }
547
548 /* Initialize LINES, allocating space for ALLOC lines initially.
549    LIMIT is the maximum possible number of lines to allocate space
550    for, ever.  */
551
552 static void
553 initlines (struct lines *lines, int alloc, int limit)
554 {
555   lines->alloc = alloc;
556   lines->lines = (struct line *) xmalloc (lines->alloc * sizeof (struct line));
557   lines->used = 0;
558   lines->limit = limit;
559 }
560
561 /* Return a pointer to the first character of the field specified
562    by KEY in LINE. */
563
564 static char *
565 begfield (const struct line *line, const struct keyfield *key)
566 {
567   register char *ptr = line->text, *lim = ptr + line->length;
568   register int sword = key->sword, schar = key->schar;
569
570   if (tab)
571     while (ptr < lim && sword--)
572       {
573         while (ptr < lim && *ptr != tab)
574           ++ptr;
575         if (ptr < lim)
576           ++ptr;
577       }
578   else
579     while (ptr < lim && sword--)
580       {
581         while (ptr < lim && blanks[UCHAR (*ptr)])
582           ++ptr;
583         while (ptr < lim && !blanks[UCHAR (*ptr)])
584           ++ptr;
585       }
586
587   if (key->skipsblanks)
588     while (ptr < lim && blanks[UCHAR (*ptr)])
589       ++ptr;
590
591   if (ptr + schar <= lim)
592     ptr += schar;
593   else
594     ptr = lim;
595
596   return ptr;
597 }
598
599 /* Return the limit of (a pointer to the first character after) the field
600    in LINE specified by KEY. */
601
602 static char *
603 limfield (const struct line *line, const struct keyfield *key)
604 {
605   register char *ptr = line->text, *lim = ptr + line->length;
606   register int eword = key->eword, echar = key->echar;
607
608   /* Note: from the POSIX spec:
609      The leading field separator itself is included in
610      a field when -t is not used.  FIXME: move this comment up... */
611
612   /* Move PTR past EWORD fields or to one past the last byte on LINE,
613      whichever comes first.  If there are more than EWORD fields, leave
614      PTR pointing at the beginning of the field having zero-based index,
615      EWORD.  If a delimiter character was specified (via -t), then that
616      `beginning' is the first character following the delimiting TAB.
617      Otherwise, leave PTR pointing at the first `blank' character after
618      the preceding field.  */
619   if (tab)
620     while (ptr < lim && eword--)
621       {
622         while (ptr < lim && *ptr != tab)
623           ++ptr;
624         if (ptr < lim && (eword || echar > 0))
625           ++ptr;
626       }
627   else
628     while (ptr < lim && eword--)
629       {
630         while (ptr < lim && blanks[UCHAR (*ptr)])
631           ++ptr;
632         while (ptr < lim && !blanks[UCHAR (*ptr)])
633           ++ptr;
634       }
635
636   /* Make LIM point to the end of (one byte past) the current field.  */
637   if (tab)
638     {
639       char *newlim;
640       newlim = memchr (ptr, tab, lim - ptr);
641       if (newlim)
642         lim = newlim;
643     }
644   else
645     {
646       char *newlim;
647       newlim = ptr;
648       while (newlim < lim && blanks[UCHAR (*newlim)])
649         ++newlim;
650       while (newlim < lim && !blanks[UCHAR (*newlim)])
651         ++newlim;
652       lim = newlim;
653     }
654
655   /* If we're skipping leading blanks, don't start counting characters
656      until after skipping past any leading blanks.  */
657   if (key->skipsblanks)
658     while (ptr < lim && blanks[UCHAR (*ptr)])
659       ++ptr;
660
661   /* Advance PTR by ECHAR (if possible), but no further than LIM.  */
662   if (ptr + echar <= lim)
663     ptr += echar;
664   else
665     ptr = lim;
666
667   return ptr;
668 }
669
670 /* FIXME */
671
672 void
673 trim_trailing_blanks (const char *a_start, char **a_end)
674 {
675   while (*a_end > a_start && blanks[UCHAR (*(*a_end - 1))])
676     --(*a_end);
677 }
678
679 /* Find the lines in BUF, storing pointers and lengths in LINES.
680    Also replace newlines in BUF with NULs. */
681
682 static void
683 findlines (struct buffer *buf, struct lines *lines)
684 {
685   register char *beg = buf->buf, *lim = buf->buf + buf->used, *ptr;
686   struct keyfield *key = keyhead.next;
687
688   lines->used = 0;
689
690   while (beg < lim && (ptr = memchr (beg, '\n', lim - beg))
691          && lines->used < lines->limit)
692     {
693       /* There are various places in the code that rely on a NUL
694          being at the end of in-core lines; NULs inside the lines
695          will not cause trouble, though. */
696       *ptr = '\0';
697
698       if (lines->used == lines->alloc)
699         {
700           lines->alloc *= 2;
701           lines->lines = (struct line *)
702             xrealloc ((char *) lines->lines,
703                       lines->alloc * sizeof (struct line));
704         }
705
706       lines->lines[lines->used].text = beg;
707       lines->lines[lines->used].length = ptr - beg;
708
709       /* Precompute the position of the first key for efficiency. */
710       if (key)
711         {
712           if (key->eword >= 0)
713             lines->lines[lines->used].keylim =
714               limfield (&lines->lines[lines->used], key);
715           else
716             lines->lines[lines->used].keylim = ptr;
717
718           if (key->sword >= 0)
719             lines->lines[lines->used].keybeg =
720               begfield (&lines->lines[lines->used], key);
721           else
722             {
723               if (key->skipsblanks)
724                 while (blanks[UCHAR (*beg)])
725                   ++beg;
726               lines->lines[lines->used].keybeg = beg;
727             }
728           if (key->skipeblanks)
729             {
730               trim_trailing_blanks (lines->lines[lines->used].keybeg,
731                                     &lines->lines[lines->used].keylim);
732             }
733         }
734       else
735         {
736           lines->lines[lines->used].keybeg = 0;
737           lines->lines[lines->used].keylim = 0;
738         }
739
740       ++lines->used;
741       beg = ptr + 1;
742     }
743
744   buf->left = lim - beg;
745 }
746
747 /* Compare strings A and B containing decimal fractions < 1.  Each string
748    should begin with a decimal point followed immediately by the digits
749    of the fraction.  Strings not of this form are considered to be zero. */
750
751 static int
752 fraccompare (register const char *a, register const char *b)
753 {
754   register tmpa = UCHAR (*a), tmpb = UCHAR (*b);
755
756 #ifdef __FreeBSD__
757   if (tmpa == decimal_point && tmpb == decimal_point)
758 #else
759   if (tmpa == '.' && tmpb == '.')
760 #endif
761     {
762       do
763         tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
764       while (tmpa == tmpb && digits[tmpa]);
765       if (digits[tmpa] && digits[tmpb])
766         return tmpa - tmpb;
767       if (digits[tmpa])
768         {
769           while (tmpa == '0')
770             tmpa = UCHAR (*++a);
771           if (digits[tmpa])
772             return 1;
773           return 0;
774         }
775       if (digits[tmpb])
776         {
777           while (tmpb == '0')
778             tmpb = UCHAR (*++b);
779           if (digits[tmpb])
780             return -1;
781           return 0;
782         }
783       return 0;
784     }
785 #ifdef __FreeBSD__
786   else if (tmpa == decimal_point)
787 #else
788   else if (tmpa == '.')
789 #endif
790     {
791       do
792         tmpa = UCHAR (*++a);
793       while (tmpa == '0');
794       if (digits[tmpa])
795         return 1;
796       return 0;
797     }
798 #ifdef __FreeBSD__
799   else if (tmpb == decimal_point)
800 #else
801   else if (tmpb == '.')
802 #endif
803     {
804       do
805         tmpb = UCHAR (*++b);
806       while (tmpb == '0');
807       if (digits[tmpb])
808         return -1;
809       return 0;
810     }
811   return 0;
812 }
813
814 /* Compare strings A and B as numbers without explicitly converting them to
815    machine numbers.  Comparatively slow for short strings, but asymptotically
816    hideously fast. */
817
818 static int
819 numcompare (register const char *a, register const char *b)
820 {
821   register int tmpa, tmpb, loga, logb, tmp;
822
823   tmpa = UCHAR (*a);
824   tmpb = UCHAR (*b);
825
826   while (blanks[tmpa])
827     tmpa = UCHAR (*++a);
828   while (blanks[tmpb])
829     tmpb = UCHAR (*++b);
830
831   if (tmpa == '-')
832     {
833       do
834         tmpa = UCHAR (*++a);
835       while (tmpa == '0');
836       if (tmpb != '-')
837         {
838 #ifdef __FreeBSD__
839           if (tmpa == decimal_point)
840 #else
841           if (tmpa == '.')
842 #endif
843             do
844               tmpa = UCHAR (*++a);
845             while (tmpa == '0');
846           if (digits[tmpa])
847             return -1;
848           while (tmpb == '0')
849             tmpb = UCHAR (*++b);
850 #ifdef __FreeBSD__
851           if (tmpb == decimal_point)
852 #else
853           if (tmpb == '.')
854 #endif
855             do
856               tmpb = UCHAR (*++b);
857             while (tmpb == '0');
858           if (digits[tmpb])
859             return -1;
860           return 0;
861         }
862       do
863         tmpb = UCHAR (*++b);
864       while (tmpb == '0');
865
866       while (tmpa == tmpb && digits[tmpa])
867         tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
868
869 #ifdef __FreeBSD__
870       if ((tmpa == decimal_point && !digits[tmpb]) ||
871           (tmpb == decimal_point && !digits[tmpa]))
872 #else
873       if ((tmpa == '.' && !digits[tmpb]) || (tmpb == '.' && !digits[tmpa]))
874 #endif
875         return -fraccompare (a, b);
876
877       if (digits[tmpa])
878         for (loga = 1; digits[UCHAR (*++a)]; ++loga)
879           ;
880       else
881         loga = 0;
882
883       if (digits[tmpb])
884         for (logb = 1; digits[UCHAR (*++b)]; ++logb)
885           ;
886       else
887         logb = 0;
888
889       if ((tmp = logb - loga) != 0)
890         return tmp;
891
892       if (!loga)
893         return 0;
894
895 #ifdef __FreeBSD__
896       return COLLDIFF (tmpb, tmpa);
897 #else
898       return tmpb - tmpa;
899 #endif
900     }
901   else if (tmpb == '-')
902     {
903       do
904         tmpb = UCHAR (*++b);
905       while (tmpb == '0');
906 #ifdef __FreeBSD__
907       if (tmpb == decimal_point)
908 #else
909       if (tmpb == '.')
910 #endif
911         do
912           tmpb = UCHAR (*++b);
913         while (tmpb == '0');
914       if (digits[tmpb])
915         return 1;
916       while (tmpa == '0')
917         tmpa = UCHAR (*++a);
918 #ifdef __FreeBSD__
919       if (tmpa == decimal_point)
920 #else
921       if (tmpa == '.')
922 #endif
923         do
924           tmpa = UCHAR (*++a);
925         while (tmpa == '0');
926       if (digits[tmpa])
927         return 1;
928       return 0;
929     }
930   else
931     {
932       while (tmpa == '0')
933         tmpa = UCHAR (*++a);
934       while (tmpb == '0')
935         tmpb = UCHAR (*++b);
936
937       while (tmpa == tmpb && digits[tmpa])
938         tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
939
940 #ifdef __FreeBSD__
941       if ((tmpa == decimal_point && !digits[tmpb]) ||
942           (tmpb == decimal_point && !digits[tmpa]))
943 #else
944       if ((tmpa == '.' && !digits[tmpb]) || (tmpb == '.' && !digits[tmpa]))
945 #endif
946         return fraccompare (a, b);
947
948       if (digits[tmpa])
949         for (loga = 1; digits[UCHAR (*++a)]; ++loga)
950           ;
951       else
952         loga = 0;
953
954       if (digits[tmpb])
955         for (logb = 1; digits[UCHAR (*++b)]; ++logb)
956           ;
957       else
958         logb = 0;
959
960       if ((tmp = loga - logb) != 0)
961         return tmp;
962
963       if (!loga)
964         return 0;
965
966 #ifdef __FreeBSD__
967       return COLLDIFF (tmpa, tmpb);
968 #else
969       return tmpa - tmpb;
970 #endif
971     }
972 }
973
974 static int
975 general_numcompare (const char *sa, const char *sb)
976 {
977   double a, b;
978   /* FIXME: add option to warn about failed conversions.  */
979   /* FIXME: maybe add option to try expensive FP conversion
980      only if A and B can't be compared more cheaply/accurately.  */
981   if (xstrtod (sa, NULL, &a))
982     {
983       a = 0;
984     }
985   if (xstrtod (sb, NULL, &b))
986     {
987       b = 0;
988     }
989   return a == b ? 0 : a < b ? -1 : 1;
990 }
991
992 /* Return an integer <= 12 associated with month name S with length LEN,
993    0 if the name in S is not recognized. */
994
995 static int
996 getmonth (const char *s, int len)
997 {
998   char month[4];
999   register int i, lo = 0, hi = 12;
1000
1001   while (len > 0 && blanks[UCHAR(*s)])
1002     ++s, --len;
1003
1004   if (len < 3)
1005     return 0;
1006
1007   for (i = 0; i < 3; ++i)
1008     month[i] = fold_toupper[UCHAR (s[i])];
1009   month[3] = '\0';
1010
1011   while (hi - lo > 1)
1012     if (strcmp (month, monthtab[(lo + hi) / 2].name) < 0)
1013       hi = (lo + hi) / 2;
1014     else
1015       lo = (lo + hi) / 2;
1016   if (!strcmp (month, monthtab[lo].name))
1017     return monthtab[lo].val;
1018   return 0;
1019 }
1020
1021 /* Compare two lines A and B trying every key in sequence until there
1022    are no more keys or a difference is found. */
1023
1024 static int
1025 keycompare (const struct line *a, const struct line *b)
1026 {
1027   register char *texta, *textb, *lima, *limb, *translate;
1028   register int *ignore;
1029   struct keyfield *key;
1030   int diff = 0, iter = 0, lena, lenb;
1031
1032   for (key = keyhead.next; key; key = key->next, ++iter)
1033     {
1034       ignore = key->ignore;
1035       translate = key->translate;
1036
1037       /* Find the beginning and limit of each field. */
1038       if (iter || a->keybeg == NULL || b->keybeg == NULL)
1039         {
1040           if (key->eword >= 0)
1041             lima = limfield (a, key), limb = limfield (b, key);
1042           else
1043             lima = a->text + a->length, limb = b->text + b->length;
1044
1045           if (key->sword >= 0)
1046             texta = begfield (a, key), textb = begfield (b, key);
1047           else
1048             {
1049               texta = a->text, textb = b->text;
1050               if (key->skipsblanks)
1051                 {
1052                   while (texta < lima && blanks[UCHAR (*texta)])
1053                     ++texta;
1054                   while (textb < limb && blanks[UCHAR (*textb)])
1055                     ++textb;
1056                 }
1057             }
1058         }
1059       else
1060         {
1061           /* For the first iteration only, the key positions have
1062              been precomputed for us. */
1063           texta = a->keybeg, lima = a->keylim;
1064           textb = b->keybeg, limb = b->keylim;
1065         }
1066
1067       /* Find the lengths. */
1068       lena = lima - texta, lenb = limb - textb;
1069       if (lena < 0)
1070         lena = 0;
1071       if (lenb < 0)
1072         lenb = 0;
1073
1074       if (key->skipeblanks)
1075         {
1076           char *a_end = texta + lena;
1077           char *b_end = textb + lenb;
1078           trim_trailing_blanks (texta, &a_end);
1079           trim_trailing_blanks (textb, &b_end);
1080           lena = a_end - texta;
1081           lenb = b_end - textb;
1082         }
1083
1084       /* Actually compare the fields. */
1085       if (key->numeric)
1086         {
1087           if (*lima || *limb)
1088             {
1089               char savea = *lima, saveb = *limb;
1090
1091               *lima = *limb = '\0';
1092               diff = numcompare (texta, textb);
1093               *lima = savea, *limb = saveb;
1094             }
1095           else
1096             diff = numcompare (texta, textb);
1097
1098           if (diff)
1099             return key->reverse ? -diff : diff;
1100           continue;
1101         }
1102       else if (key->general_numeric)
1103         {
1104           if (*lima || *limb)
1105             {
1106               char savea = *lima, saveb = *limb;
1107
1108               *lima = *limb = '\0';
1109               diff = general_numcompare (texta, textb);
1110               *lima = savea, *limb = saveb;
1111             }
1112           else
1113             diff = general_numcompare (texta, textb);
1114
1115           if (diff)
1116             return key->reverse ? -diff : diff;
1117           continue;
1118         }
1119       else if (key->month)
1120         {
1121           diff = getmonth (texta, lena) - getmonth (textb, lenb);
1122           if (diff)
1123             return key->reverse ? -diff : diff;
1124           continue;
1125         }
1126       else if (ignore && translate)
1127
1128 #ifdef __FreeBSD__
1129 #define CMP_FUNC(A, B) COLLDIFF ((A), (B))
1130 #else
1131 #define CMP_FUNC(A, B) (A) - (B)
1132 #endif
1133 #define CMP_WITH_IGNORE(A, B)                                           \
1134   do                                                                    \
1135     {                                                                   \
1136           while (texta < lima && textb < limb)                          \
1137             {                                                           \
1138               while (texta < lima && ignore[UCHAR (*texta)])            \
1139                 ++texta;                                                \
1140               while (textb < limb && ignore[UCHAR (*textb)])            \
1141                 ++textb;                                                \
1142               if (texta < lima && textb < limb)                         \
1143                 {                                                       \
1144                   if ((A) != (B))                                       \
1145                     {                                                   \
1146                       diff = CMP_FUNC((A), (B));                        \
1147                       break;                                            \
1148                     }                                                   \
1149                   ++texta;                                              \
1150                   ++textb;                                              \
1151                 }                                                       \
1152                                                                         \
1153               if (texta == lima && textb < limb && !ignore[UCHAR (*textb)]) \
1154                 diff = -1;                                              \
1155               else if (texta < lima && textb == limb                    \
1156                        && !ignore[UCHAR (*texta)])                      \
1157                 diff = 1;                                               \
1158             }                                                           \
1159                                                                         \
1160           if (diff == 0)                                                \
1161             {                                                           \
1162               while (texta < lima && ignore[UCHAR (*texta)])            \
1163                 ++texta;                                                \
1164               while (textb < limb && ignore[UCHAR (*textb)])            \
1165                 ++textb;                                                \
1166                                                                         \
1167               if (texta == lima && textb < limb)                        \
1168                 diff = -1;                                              \
1169               else if (texta < lima && textb == limb)                   \
1170                 diff = 1;                                               \
1171             }                                                           \
1172           /* Relative lengths are meaningless if characters were ignored.  \
1173              Handling this case here avoids what might be an invalid length  \
1174              comparison below.  */                                      \
1175           if (diff == 0 && texta == lima && textb == limb)              \
1176             return 0;                                                   \
1177     }                                                                   \
1178   while (0)
1179
1180         CMP_WITH_IGNORE (translate[UCHAR (*texta)], translate[UCHAR (*textb)]);
1181       else if (ignore)
1182         CMP_WITH_IGNORE (*texta, *textb);
1183       else if (translate)
1184         while (texta < lima && textb < limb)
1185           {
1186             if (translate[UCHAR (*texta++)] != translate[UCHAR (*textb++)])
1187               {
1188 #ifdef __FreeBSD__
1189                 diff = COLLDIFF (translate[UCHAR (*--texta)],
1190                           translate[UCHAR (*--textb)]);
1191 #else
1192                 diff = (translate[UCHAR (*--texta)]
1193                         - translate[UCHAR (*--textb)]);
1194 #endif
1195                 break;
1196               }
1197           }
1198       else
1199 #ifdef __FreeBSD__
1200         diff = collcmp (texta, textb, min (lena, lenb));
1201 #else
1202         diff = memcmp (texta, textb, min (lena, lenb));
1203 #endif
1204
1205       if (diff)
1206         return key->reverse ? -diff : diff;
1207       if ((diff = lena - lenb) != 0)
1208         return key->reverse ? -diff : diff;
1209     }
1210
1211   return 0;
1212 }
1213
1214 /* Compare two lines A and B, returning negative, zero, or positive
1215    depending on whether A compares less than, equal to, or greater than B. */
1216
1217 static int
1218 compare (register const struct line *a, register const struct line *b)
1219 {
1220   int diff, tmpa, tmpb, mini;
1221
1222   /* First try to compare on the specified keys (if any).
1223      The only two cases with no key at all are unadorned sort,
1224      and unadorned sort -r. */
1225   if (keyhead.next)
1226     {
1227       diff = keycompare (a, b);
1228       if (diff != 0)
1229         return diff;
1230       if (unique || stable)
1231         return 0;
1232     }
1233
1234   /* If the keys all compare equal (or no keys were specified)
1235      fall through to the default byte-by-byte comparison. */
1236   tmpa = a->length, tmpb = b->length;
1237   mini = min (tmpa, tmpb);
1238   if (mini == 0)
1239     diff = tmpa - tmpb;
1240   else
1241     {
1242       char *ap = a->text, *bp = b->text;
1243
1244 #ifndef __FreeBSD__
1245       diff = UCHAR (*ap) - UCHAR (*bp);
1246       if (diff == 0)
1247         {
1248 #endif
1249 #ifdef __FreeBSD__
1250           diff = collcmp (ap, bp, mini);
1251 #else
1252           diff = memcmp (ap, bp, mini);
1253 #endif
1254           if (diff == 0)
1255             diff = tmpa - tmpb;
1256 #ifndef __FreeBSD__
1257         }
1258 #endif
1259     }
1260
1261   return reverse ? -diff : diff;
1262 }
1263
1264 /* Check that the lines read from the given FP come in order.  Return
1265    1 if they do and 0 if there is a disorder.
1266    FIXME: return number of first out-of-order line if not sorted.  */
1267
1268 static int
1269 checkfp (FILE *fp)
1270 {
1271   struct buffer buf;            /* Input buffer. */
1272   struct lines lines;           /* Lines scanned from the buffer. */
1273   struct line temp;             /* Copy of previous line. */
1274   int cc;                       /* Character count. */
1275   int alloc, sorted = 1;
1276
1277   initbuf (&buf, mergealloc);
1278   initlines (&lines, mergealloc / linelength + 1,
1279              LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
1280   alloc = linelength;
1281   temp.text = xmalloc (alloc);
1282
1283   cc = fillbuf (&buf, fp);
1284   if (cc == 0)
1285     goto finish;
1286
1287   findlines (&buf, &lines);
1288
1289   while (1)
1290     {
1291       struct line *prev_line;   /* Pointer to previous line. */
1292       int cmp;                  /* Result of calling compare. */
1293       int i;
1294
1295       /* Compare each line in the buffer with its successor. */
1296       for (i = 0; i < lines.used - 1; ++i)
1297         {
1298           cmp = compare (&lines.lines[i], &lines.lines[i + 1]);
1299           if ((unique && cmp >= 0) || (cmp > 0))
1300             {
1301               sorted = 0;
1302               goto finish;
1303             }
1304         }
1305
1306       /* Save the last line of the buffer and refill the buffer. */
1307       prev_line = lines.lines + (lines.used - 1);
1308       if (prev_line->length > alloc)
1309         {
1310           while (prev_line->length + 1 > alloc)
1311             alloc *= 2;
1312           temp.text = xrealloc (temp.text, alloc);
1313         }
1314       memcpy (temp.text, prev_line->text, prev_line->length + 1);
1315       temp.length = prev_line->length;
1316       temp.keybeg = temp.text + (prev_line->keybeg - prev_line->text);
1317       temp.keylim = temp.text + (prev_line->keylim - prev_line->text);
1318
1319       cc = fillbuf (&buf, fp);
1320       if (cc == 0)
1321         break;
1322
1323       findlines (&buf, &lines);
1324       /* Make sure the line saved from the old buffer contents is
1325          less than or equal to the first line of the new buffer. */
1326       cmp = compare (&temp, &lines.lines[0]);
1327       if ((unique && cmp >= 0) || (cmp > 0))
1328         {
1329           sorted = 0;
1330           break;
1331         }
1332     }
1333
1334 finish:
1335   xfclose (fp);
1336   free (buf.buf);
1337   free ((char *) lines.lines);
1338   free (temp.text);
1339   return sorted;
1340 }
1341
1342 /* Merge lines from FPS onto OFP.  NFPS cannot be greater than NMERGE.
1343    Close FPS before returning. */
1344
1345 static void
1346 mergefps (FILE **fps, register int nfps, FILE *ofp)
1347 {
1348   struct buffer buffer[NMERGE]; /* Input buffers for each file. */
1349   struct lines lines[NMERGE];   /* Line tables for each buffer. */
1350   struct line saved;            /* Saved line for unique check. */
1351   int savedflag = 0;            /* True if there is a saved line. */
1352   int savealloc;                /* Size allocated for the saved line. */
1353   int cur[NMERGE];              /* Current line in each line table. */
1354   int ord[NMERGE];              /* Table representing a permutation of fps,
1355                                    such that lines[ord[0]].lines[cur[ord[0]]]
1356                                    is the smallest line and will be next
1357                                    output. */
1358   register int i, j, t;
1359
1360 #ifdef lint  /* Suppress `used before initialized' warning.  */
1361   savealloc = 0;
1362 #endif
1363
1364   /* Allocate space for a saved line if necessary. */
1365   if (unique)
1366     {
1367       savealloc = linelength;
1368       saved.text = xmalloc (savealloc);
1369     }
1370
1371   /* Read initial lines from each input file. */
1372   for (i = 0; i < nfps; ++i)
1373     {
1374       initbuf (&buffer[i], mergealloc);
1375       /* If a file is empty, eliminate it from future consideration. */
1376       while (i < nfps && !fillbuf (&buffer[i], fps[i]))
1377         {
1378           xfclose (fps[i]);
1379           --nfps;
1380           for (j = i; j < nfps; ++j)
1381             fps[j] = fps[j + 1];
1382         }
1383       if (i == nfps)
1384         free (buffer[i].buf);
1385       else
1386         {
1387           initlines (&lines[i], mergealloc / linelength + 1,
1388                      LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
1389           findlines (&buffer[i], &lines[i]);
1390           cur[i] = 0;
1391         }
1392     }
1393
1394   /* Set up the ord table according to comparisons among input lines.
1395      Since this only reorders two items if one is strictly greater than
1396      the other, it is stable. */
1397   for (i = 0; i < nfps; ++i)
1398     ord[i] = i;
1399   for (i = 1; i < nfps; ++i)
1400     if (compare (&lines[ord[i - 1]].lines[cur[ord[i - 1]]],
1401                  &lines[ord[i]].lines[cur[ord[i]]]) > 0)
1402       t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0;
1403
1404   /* Repeatedly output the smallest line until no input remains. */
1405   while (nfps)
1406     {
1407       /* If uniqified output is turned on, output only the first of
1408          an identical series of lines. */
1409       if (unique)
1410         {
1411           if (savedflag && compare (&saved, &lines[ord[0]].lines[cur[ord[0]]]))
1412             {
1413               xfwrite (saved.text, 1, saved.length, ofp);
1414               putc ('\n', ofp);
1415               savedflag = 0;
1416             }
1417           if (!savedflag)
1418             {
1419               if (savealloc < lines[ord[0]].lines[cur[ord[0]]].length + 1)
1420                 {
1421                   while (savealloc < lines[ord[0]].lines[cur[ord[0]]].length + 1)
1422                     savealloc *= 2;
1423                   saved.text = xrealloc (saved.text, savealloc);
1424                 }
1425               saved.length = lines[ord[0]].lines[cur[ord[0]]].length;
1426               memcpy (saved.text, lines[ord[0]].lines[cur[ord[0]]].text,
1427                      saved.length + 1);
1428               if (lines[ord[0]].lines[cur[ord[0]]].keybeg != NULL)
1429                 {
1430                   saved.keybeg = saved.text +
1431                     (lines[ord[0]].lines[cur[ord[0]]].keybeg
1432                      - lines[ord[0]].lines[cur[ord[0]]].text);
1433                 }
1434               if (lines[ord[0]].lines[cur[ord[0]]].keylim != NULL)
1435                 {
1436                   saved.keylim = saved.text +
1437                     (lines[ord[0]].lines[cur[ord[0]]].keylim
1438                      - lines[ord[0]].lines[cur[ord[0]]].text);
1439                 }
1440               savedflag = 1;
1441             }
1442         }
1443       else
1444         {
1445           xfwrite (lines[ord[0]].lines[cur[ord[0]]].text, 1,
1446                    lines[ord[0]].lines[cur[ord[0]]].length, ofp);
1447           putc ('\n', ofp);
1448         }
1449
1450       /* Check if we need to read more lines into core. */
1451       if (++cur[ord[0]] == lines[ord[0]].used)
1452         if (fillbuf (&buffer[ord[0]], fps[ord[0]]))
1453           {
1454             findlines (&buffer[ord[0]], &lines[ord[0]]);
1455             cur[ord[0]] = 0;
1456           }
1457         else
1458           {
1459             /* We reached EOF on fps[ord[0]]. */
1460             for (i = 1; i < nfps; ++i)
1461               if (ord[i] > ord[0])
1462                 --ord[i];
1463             --nfps;
1464             xfclose (fps[ord[0]]);
1465             free (buffer[ord[0]].buf);
1466             free ((char *) lines[ord[0]].lines);
1467             for (i = ord[0]; i < nfps; ++i)
1468               {
1469                 fps[i] = fps[i + 1];
1470                 buffer[i] = buffer[i + 1];
1471                 lines[i] = lines[i + 1];
1472                 cur[i] = cur[i + 1];
1473               }
1474             for (i = 0; i < nfps; ++i)
1475               ord[i] = ord[i + 1];
1476             continue;
1477           }
1478
1479       /* The new line just read in may be larger than other lines
1480          already in core; push it back in the queue until we encounter
1481          a line larger than it. */
1482       for (i = 1; i < nfps; ++i)
1483         {
1484           t = compare (&lines[ord[0]].lines[cur[ord[0]]],
1485                        &lines[ord[i]].lines[cur[ord[i]]]);
1486           if (!t)
1487             t = ord[0] - ord[i];
1488           if (t < 0)
1489             break;
1490         }
1491       t = ord[0];
1492       for (j = 1; j < i; ++j)
1493         ord[j - 1] = ord[j];
1494       ord[i - 1] = t;
1495     }
1496
1497   if (unique && savedflag)
1498     {
1499       xfwrite (saved.text, 1, saved.length, ofp);
1500       putc ('\n', ofp);
1501       free (saved.text);
1502     }
1503 }
1504
1505 /* Sort the array LINES with NLINES members, using TEMP for temporary space. */
1506
1507 static void
1508 sortlines (struct line *lines, int nlines, struct line *temp)
1509 {
1510   register struct line *lo, *hi, *t;
1511   register int nlo, nhi;
1512
1513   if (nlines == 2)
1514     {
1515       if (compare (&lines[0], &lines[1]) > 0)
1516         *temp = lines[0], lines[0] = lines[1], lines[1] = *temp;
1517       return;
1518     }
1519
1520   nlo = nlines / 2;
1521   lo = lines;
1522   nhi = nlines - nlo;
1523   hi = lines + nlo;
1524
1525   if (nlo > 1)
1526     sortlines (lo, nlo, temp);
1527
1528   if (nhi > 1)
1529     sortlines (hi, nhi, temp);
1530
1531   t = temp;
1532
1533   while (nlo && nhi)
1534     if (compare (lo, hi) <= 0)
1535       *t++ = *lo++, --nlo;
1536     else
1537       *t++ = *hi++, --nhi;
1538   while (nlo--)
1539     *t++ = *lo++;
1540
1541   for (lo = lines, nlo = nlines - nhi, t = temp; nlo; --nlo)
1542     *lo++ = *t++;
1543 }
1544
1545 /* Check that each of the NFILES FILES is ordered.
1546    Return a count of disordered files. */
1547
1548 static int
1549 check (char **files, int nfiles)
1550 {
1551   int i, disorders = 0;
1552   FILE *fp;
1553
1554   for (i = 0; i < nfiles; ++i)
1555     {
1556       fp = xfopen (files[i], "r");
1557       if (!checkfp (fp))
1558         {
1559           fprintf (stderr, _("%s: disorder on %s\n"), program_name, files[i]);
1560           ++disorders;
1561         }
1562     }
1563   return disorders;
1564 }
1565
1566 /* Merge NFILES FILES onto OFP. */
1567
1568 static void
1569 merge (char **files, int nfiles, FILE *ofp)
1570 {
1571   int i, j, t;
1572   char *temp;
1573   FILE *fps[NMERGE], *tfp;
1574
1575   while (nfiles > NMERGE)
1576     {
1577       t = 0;
1578       for (i = 0; i < nfiles / NMERGE; ++i)
1579         {
1580           for (j = 0; j < NMERGE; ++j)
1581             fps[j] = xfopen (files[i * NMERGE + j], "r");
1582           tfp = xtmpfopen (temp = tempname ());
1583           mergefps (fps, NMERGE, tfp);
1584           xfclose (tfp);
1585           for (j = 0; j < NMERGE; ++j)
1586             zaptemp (files[i * NMERGE + j]);
1587           files[t++] = temp;
1588         }
1589       for (j = 0; j < nfiles % NMERGE; ++j)
1590         fps[j] = xfopen (files[i * NMERGE + j], "r");
1591       tfp = xtmpfopen (temp = tempname ());
1592       mergefps (fps, nfiles % NMERGE, tfp);
1593       xfclose (tfp);
1594       for (j = 0; j < nfiles % NMERGE; ++j)
1595         zaptemp (files[i * NMERGE + j]);
1596       files[t++] = temp;
1597       nfiles = t;
1598     }
1599
1600   for (i = 0; i < nfiles; ++i)
1601     fps[i] = xfopen (files[i], "r");
1602   mergefps (fps, i, ofp);
1603   for (i = 0; i < nfiles; ++i)
1604     zaptemp (files[i]);
1605 }
1606
1607 /* Sort NFILES FILES onto OFP. */
1608
1609 static void
1610 sort (char **files, int nfiles, FILE *ofp)
1611 {
1612   struct buffer buf;
1613   struct lines lines;
1614   struct line *tmp;
1615   int i, ntmp;
1616   FILE *fp, *tfp;
1617   struct tempnode *node;
1618   int n_temp_files = 0;
1619   char **tempfiles;
1620
1621   initbuf (&buf, sortalloc);
1622   initlines (&lines, sortalloc / linelength + 1,
1623              LINEALLOC / sizeof (struct line));
1624   ntmp = lines.alloc;
1625   tmp = (struct line *) xmalloc (ntmp * sizeof (struct line));
1626
1627   while (nfiles--)
1628     {
1629       fp = xfopen (*files++, "r");
1630       while (fillbuf (&buf, fp))
1631         {
1632           findlines (&buf, &lines);
1633           if (lines.used > ntmp)
1634             {
1635               while (lines.used > ntmp)
1636                 ntmp *= 2;
1637               tmp = (struct line *)
1638                 xrealloc ((char *) tmp, ntmp * sizeof (struct line));
1639             }
1640           sortlines (lines.lines, lines.used, tmp);
1641           if (feof (fp) && !nfiles && !n_temp_files && !buf.left)
1642             tfp = ofp;
1643           else
1644             {
1645               ++n_temp_files;
1646               tfp = xtmpfopen (tempname ());
1647             }
1648           for (i = 0; i < lines.used; ++i)
1649             if (!unique || i == 0
1650                 || compare (&lines.lines[i], &lines.lines[i - 1]))
1651               {
1652                 xfwrite (lines.lines[i].text, 1, lines.lines[i].length, tfp);
1653                 putc ('\n', tfp);
1654               }
1655           if (tfp != ofp)
1656             xfclose (tfp);
1657         }
1658       xfclose (fp);
1659     }
1660
1661   free (buf.buf);
1662   free ((char *) lines.lines);
1663   free ((char *) tmp);
1664
1665   if (n_temp_files)
1666     {
1667       tempfiles = (char **) xmalloc (n_temp_files * sizeof (char *));
1668       i = n_temp_files;
1669       for (node = temphead.next; i > 0; node = node->next)
1670         tempfiles[--i] = node->name;
1671       merge (tempfiles, n_temp_files, ofp);
1672       free ((char *) tempfiles);
1673     }
1674 }
1675
1676 /* Insert key KEY at the end of the list (`keyhead'). */
1677
1678 static void
1679 insertkey (struct keyfield *key)
1680 {
1681   struct keyfield *k = &keyhead;
1682
1683   while (k->next)
1684     k = k->next;
1685   k->next = key;
1686   key->next = NULL;
1687 }
1688
1689 static void
1690 badfieldspec (const char *s)
1691 {
1692   error (2, 0, _("invalid field specification `%s'"), s);
1693 }
1694
1695 /* Handle interrupts and hangups. */
1696
1697 static void
1698 sighandler (int sig)
1699 {
1700 #ifdef SA_INTERRUPT
1701   struct sigaction sigact;
1702
1703   sigact.sa_handler = SIG_DFL;
1704   sigemptyset (&sigact.sa_mask);
1705   sigact.sa_flags = 0;
1706   sigaction (sig, &sigact, NULL);
1707 #else                           /* !SA_INTERRUPT */
1708   signal (sig, SIG_DFL);
1709 #endif                          /* SA_INTERRUPT */
1710   cleanup ();
1711   kill (getpid (), sig);
1712 }
1713
1714 /* Set the ordering options for KEY specified in S.
1715    Return the address of the first character in S that
1716    is not a valid ordering option.
1717    BLANKTYPE is the kind of blanks that 'b' should skip. */
1718
1719 static char *
1720 set_ordering (register const char *s, struct keyfield *key,
1721               enum blanktype blanktype)
1722 {
1723   while (*s)
1724     {
1725       switch (*s)
1726         {
1727         case 'b':
1728           if (blanktype == bl_start || blanktype == bl_both)
1729             key->skipsblanks = 1;
1730           if (blanktype == bl_end || blanktype == bl_both)
1731             key->skipeblanks = 1;
1732           break;
1733         case 'd':
1734           key->ignore = nondictionary;
1735           break;
1736         case 'f':
1737           key->translate = fold_toupper;
1738           break;
1739         case 'g':
1740           key->general_numeric = 1;
1741           break;
1742         case 'i':
1743           key->ignore = nonprinting;
1744           break;
1745         case 'M':
1746           key->month = 1;
1747           break;
1748         case 'n':
1749           key->numeric = 1;
1750           if (blanktype == bl_start || blanktype == bl_both)
1751             key->skipsblanks = 1;
1752           if (blanktype == bl_end || blanktype == bl_both)
1753             key->skipeblanks = 1;
1754           break;
1755         case 'r':
1756           key->reverse = 1;
1757           break;
1758         default:
1759           return (char *) s;
1760         }
1761       ++s;
1762     }
1763   return (char *) s;
1764 }
1765
1766 int
1767 main (int argc, char **argv)
1768 {
1769   struct keyfield *key = NULL, gkey;
1770   char *s;
1771   int i, t, t2;
1772   int checkonly = 0, mergeonly = 0, nfiles = 0;
1773   char *minus = "-", *outfile = minus, **files, *tmp;
1774   FILE *ofp;
1775 #ifdef SA_INTERRUPT
1776   struct sigaction oldact, newact;
1777 #endif                          /* SA_INTERRUPT */
1778
1779 #ifdef __FreeBSD__
1780   (void) setlocale(LC_ALL, "");
1781   decimal_point = localeconv()->decimal_point[0];
1782 #endif
1783   program_name = argv[0];
1784
1785   parse_long_options (argc, argv, "sort", version_string, usage);
1786
1787   have_read_stdin = 0;
1788   inittables ();
1789
1790   temp_file_prefix = getenv ("TMPDIR");
1791   if (temp_file_prefix == NULL)
1792     temp_file_prefix = DEFAULT_TMPDIR;
1793
1794 #ifdef SA_INTERRUPT
1795   newact.sa_handler = sighandler;
1796   sigemptyset (&newact.sa_mask);
1797   newact.sa_flags = 0;
1798
1799   sigaction (SIGINT, NULL, &oldact);
1800   if (oldact.sa_handler != SIG_IGN)
1801     sigaction (SIGINT, &newact, NULL);
1802   sigaction (SIGHUP, NULL, &oldact);
1803   if (oldact.sa_handler != SIG_IGN)
1804     sigaction (SIGHUP, &newact, NULL);
1805   sigaction (SIGPIPE, NULL, &oldact);
1806   if (oldact.sa_handler != SIG_IGN)
1807     sigaction (SIGPIPE, &newact, NULL);
1808   sigaction (SIGTERM, NULL, &oldact);
1809   if (oldact.sa_handler != SIG_IGN)
1810     sigaction (SIGTERM, &newact, NULL);
1811 #else                           /* !SA_INTERRUPT */
1812   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1813     signal (SIGINT, sighandler);
1814   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1815     signal (SIGHUP, sighandler);
1816   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
1817     signal (SIGPIPE, sighandler);
1818   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
1819     signal (SIGTERM, sighandler);
1820 #endif                          /* !SA_INTERRUPT */
1821
1822   gkey.sword = gkey.eword = -1;
1823   gkey.ignore = NULL;
1824   gkey.translate = NULL;
1825   gkey.numeric =  gkey.general_numeric = gkey.month = gkey.reverse = 0;
1826   gkey.skipsblanks = gkey.skipeblanks = 0;
1827
1828   files = (char **) xmalloc (sizeof (char *) * argc);
1829
1830   for (i = 1; i < argc; ++i)
1831     {
1832       if (argv[i][0] == '+')
1833         {
1834           if (key)
1835             insertkey (key);
1836           key = (struct keyfield *) xmalloc (sizeof (struct keyfield));
1837           key->eword = -1;
1838           key->ignore = NULL;
1839           key->translate = NULL;
1840           key->skipsblanks = key->skipeblanks = 0;
1841           key->numeric = key->general_numeric = key->month = key->reverse = 0;
1842           s = argv[i] + 1;
1843           if (! (digits[UCHAR (*s)] || (*s == '.' && digits[UCHAR (s[1])])))
1844             badfieldspec (argv[i]);
1845           for (t = 0; digits[UCHAR (*s)]; ++s)
1846             t = 10 * t + *s - '0';
1847           t2 = 0;
1848           if (*s == '.')
1849             for (++s; digits[UCHAR (*s)]; ++s)
1850               t2 = 10 * t2 + *s - '0';
1851           if (t2 || t)
1852             {
1853               key->sword = t;
1854               key->schar = t2;
1855             }
1856           else
1857             key->sword = -1;
1858           s = set_ordering (s, key, bl_start);
1859           if (*s)
1860             badfieldspec (argv[i]);
1861         }
1862       else if (argv[i][0] == '-' && argv[i][1])
1863         {
1864           s = argv[i] + 1;
1865           if (digits[UCHAR (*s)] || (*s == '.' && digits[UCHAR (s[1])]))
1866             {
1867               if (!key)
1868                 usage (2);
1869               for (t = 0; digits[UCHAR (*s)]; ++s)
1870                 t = t * 10 + *s - '0';
1871               t2 = 0;
1872               if (*s == '.')
1873                 for (++s; digits[UCHAR (*s)]; ++s)
1874                   t2 = t2 * 10 + *s - '0';
1875               key->eword = t;
1876               key->echar = t2;
1877               s = set_ordering (s, key, bl_end);
1878               if (*s)
1879                 badfieldspec (argv[i]);
1880               insertkey (key);
1881               key = NULL;
1882             }
1883           else
1884             while (*s)
1885               {
1886                 s = set_ordering (s, &gkey, bl_both);
1887                 switch (*s)
1888                   {
1889                   case '\0':
1890                     break;
1891                   case 'c':
1892                     checkonly = 1;
1893                     break;
1894                   case 'k':
1895                     if (s[1])
1896                       ++s;
1897                     else
1898                       {
1899                         if (i == argc - 1)
1900                           error (2, 0, _("option `-k' requires an argument"));
1901                         else
1902                           s = argv[++i];
1903                       }
1904                     if (key)
1905                       insertkey (key);
1906                     key = (struct keyfield *)
1907                       xmalloc (sizeof (struct keyfield));
1908                     memset (key, 0, sizeof (struct keyfield));
1909                     key->eword = -1;
1910                     key->ignore = NULL;
1911                     key->translate = NULL;
1912                     key->skipsblanks = key->skipeblanks = 0;
1913                     key->numeric = key->month = key->reverse = 0;
1914                     /* Get POS1. */
1915                     if (!digits[UCHAR (*s)])
1916                       badfieldspec (argv[i]);
1917                     for (t = 0; digits[UCHAR (*s)]; ++s)
1918                       t = 10 * t + *s - '0';
1919                     if (t == 0)
1920                       {
1921                         /* Provoke with `sort -k0' */
1922                         error (0, 0, _("the starting field number argument \
1923 to the `-k' option must be positive"));
1924                         badfieldspec (argv[i]);
1925                       }
1926                     --t;
1927                     t2 = 0;
1928                     if (*s == '.')
1929                       {
1930                         if (!digits[UCHAR (s[1])])
1931                           {
1932                             /* Provoke with `sort -k1.' */
1933                             error (0, 0, _("starting field spec has `.' but \
1934 lacks following character offset"));
1935                             badfieldspec (argv[i]);
1936                           }
1937                         for (++s; digits[UCHAR (*s)]; ++s)
1938                           t2 = 10 * t2 + *s - '0';
1939                         if (t2 == 0)
1940                           {
1941                             /* Provoke with `sort -k1.0' */
1942                             error (0, 0, _("starting field character offset \
1943 argument to the `-k' option\nmust be positive"));
1944                             badfieldspec (argv[i]);
1945                           }
1946                         --t2;
1947                       }
1948                     if (t2 || t)
1949                       {
1950                         key->sword = t;
1951                         key->schar = t2;
1952                       }
1953                     else
1954                       key->sword = -1;
1955                     s = set_ordering (s, key, bl_start);
1956                     if (*s == 0)
1957                       {
1958                         key->eword = -1;
1959                         key->echar = 0;
1960                       }
1961                     else if (*s != ',')
1962                       badfieldspec (argv[i]);
1963                     else if (*s == ',')
1964                       {
1965                         /* Skip over comma.  */
1966                         ++s;
1967                         if (*s == 0)
1968                           {
1969                             /* Provoke with `sort -k1,' */
1970                             error (0, 0, _("field specification has `,' but \
1971 lacks following field spec"));
1972                             badfieldspec (argv[i]);
1973                           }
1974                         /* Get POS2. */
1975                         for (t = 0; digits[UCHAR (*s)]; ++s)
1976                           t = t * 10 + *s - '0';
1977                         if (t == 0)
1978                           {
1979                             /* Provoke with `sort -k1,0' */
1980                             error (0, 0, _("ending field number argument \
1981 to the `-k' option must be positive"));
1982                             badfieldspec (argv[i]);
1983                           }
1984                         --t;
1985                         t2 = 0;
1986                         if (*s == '.')
1987                           {
1988                             if (!digits[UCHAR (s[1])])
1989                               {
1990                                 /* Provoke with `sort -k1,1.' */
1991                                 error (0, 0, _("ending field spec has `.' \
1992 but lacks following character offset"));
1993                                 badfieldspec (argv[i]);
1994                               }
1995                             for (++s; digits[UCHAR (*s)]; ++s)
1996                               t2 = t2 * 10 + *s - '0';
1997                           }
1998                         else
1999                           {
2000                             /* `-k 2,3' is equivalent to `+1 -3'.  */
2001                             ++t;
2002                           }
2003                         key->eword = t;
2004                         key->echar = t2;
2005                         s = set_ordering (s, key, bl_end);
2006                         if (*s)
2007                           badfieldspec (argv[i]);
2008                       }
2009                     insertkey (key);
2010                     key = NULL;
2011                     goto outer;
2012                   case 'm':
2013                     mergeonly = 1;
2014                     break;
2015                   case 'o':
2016                     if (s[1])
2017                       outfile = s + 1;
2018                     else
2019                       {
2020                         if (i == argc - 1)
2021                           error (2, 0, _("option `-o' requires an argument"));
2022                         else
2023                           outfile = argv[++i];
2024                       }
2025                     goto outer;
2026                   case 's':
2027                     stable = 1;
2028                     break;
2029                   case 't':
2030                     if (s[1])
2031                       tab = *++s;
2032                     else if (i < argc - 1)
2033                       {
2034                         tab = *argv[++i];
2035                         goto outer;
2036                       }
2037                     else
2038                       error (2, 0, _("option `-t' requires an argument"));
2039                     break;
2040                   case 'T':
2041                     if (s[1])
2042                       temp_file_prefix = ++s;
2043                     else
2044                       {
2045                         if (i < argc - 1)
2046                           temp_file_prefix = argv[++i];
2047                         else
2048                           error (2, 0, _("option `-T' requires an argument"));
2049                       }
2050                     goto outer;
2051                     /* break; */
2052                   case 'u':
2053                     unique = 1;
2054                     break;
2055                   case 'y':
2056                     /* Accept and ignore e.g. -y0 for compatibility with
2057                        Solaris 2.  */
2058                     goto outer;
2059                   default:
2060                     fprintf (stderr, _("%s: unrecognized option `-%c'\n"),
2061                              argv[0], *s);
2062                     usage (2);
2063                   }
2064                 if (*s)
2065                   ++s;
2066               }
2067         }
2068       else                      /* Not an option. */
2069         {
2070           files[nfiles++] = argv[i];
2071         }
2072     outer:;
2073     }
2074
2075   if (key)
2076     insertkey (key);
2077
2078   /* Inheritance of global options to individual keys. */
2079   for (key = keyhead.next; key; key = key->next)
2080     if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse
2081         && !key->skipeblanks && !key->month && !key->numeric
2082         && !key->general_numeric)
2083       {
2084         key->ignore = gkey.ignore;
2085         key->translate = gkey.translate;
2086         key->skipsblanks = gkey.skipsblanks;
2087         key->skipeblanks = gkey.skipeblanks;
2088         key->month = gkey.month;
2089         key->numeric = gkey.numeric;
2090         key->general_numeric = gkey.general_numeric;
2091         key->reverse = gkey.reverse;
2092       }
2093
2094   if (!keyhead.next && (gkey.ignore || gkey.translate || gkey.skipsblanks
2095                         || gkey.skipeblanks || gkey.month || gkey.numeric
2096                         || gkey.general_numeric))
2097     insertkey (&gkey);
2098   reverse = gkey.reverse;
2099
2100   if (nfiles == 0)
2101     {
2102       nfiles = 1;
2103       files = &minus;
2104     }
2105
2106   if (checkonly)
2107     exit (check (files, nfiles) != 0);
2108
2109   if (strcmp (outfile, "-"))
2110     {
2111       struct stat outstat;
2112       if (stat (outfile, &outstat) == 0)
2113         {
2114           /* The following code prevents a race condition when
2115              people use the brain dead shell programming idiom:
2116                   cat file | sort -o file
2117              This feature is provided for historical compatibility,
2118              but we strongly discourage ever relying on this in
2119              new shell programs. */
2120
2121           /* Temporarily copy each input file that might be another name
2122              for the output file.  When in doubt (e.g. a pipe), copy.  */
2123           for (i = 0; i < nfiles; ++i)
2124             {
2125               char buf[8192];
2126               FILE *fp;
2127               int cc;
2128
2129               if (S_ISREG (outstat.st_mode) && strcmp (outfile, files[i]))
2130                 {
2131                   struct stat instat;
2132                   if ((strcmp (files[i], "-")
2133                        ? stat (files[i], &instat)
2134                        : fstat (fileno (stdin), &instat)) != 0)
2135                     {
2136                       error (0, errno, "%s", files[i]);
2137                       cleanup ();
2138                       exit (2);
2139                     }
2140                   if (S_ISREG (instat.st_mode)
2141                       && (instat.st_ino != outstat.st_ino
2142                           || instat.st_dev != outstat.st_dev))
2143                     {
2144                       /* We know the files are distinct.  */
2145                       continue;
2146                     }
2147                 }
2148
2149               fp = xfopen (files[i], "r");
2150               tmp = tempname ();
2151               ofp = xtmpfopen (tmp);
2152               while ((cc = fread (buf, 1, sizeof buf, fp)) > 0)
2153                 xfwrite (buf, 1, cc, ofp);
2154               if (ferror (fp))
2155                 {
2156                   error (0, errno, "%s", files[i]);
2157                   cleanup ();
2158                   exit (2);
2159                 }
2160               xfclose (ofp);
2161               xfclose (fp);
2162               files[i] = tmp;
2163             }
2164         }
2165       ofp = xfopen (outfile, "w");
2166     }
2167   else
2168     ofp = stdout;
2169
2170   if (mergeonly)
2171     merge (files, nfiles, ofp);
2172   else
2173     sort (files, nfiles, ofp);
2174   cleanup ();
2175
2176   /* If we wait for the implicit flush on exit, and the parent process
2177      has closed stdout (e.g., exec >&- in a shell), then the output file
2178      winds up empty.  I don't understand why.  This is under SunOS,
2179      Solaris, Ultrix, and Irix.  This premature fflush makes the output
2180      reappear. --karl@cs.umb.edu  */
2181   if (fflush (ofp) < 0)
2182     error (1, errno, _("%s: write error"), outfile);
2183
2184   if (have_read_stdin && fclose (stdin) == EOF)
2185     error (1, errno, outfile);
2186   if (ferror (stdout) || fclose (stdout) == EOF)
2187     error (1, errno, _("%s: write error"), outfile);
2188
2189   exit (0);
2190 }