.
[coreutils.git] / src / sort.c
blob83f345ef877b3220ee9b1ee59a03707e00658fbb
1 /* sort - sort lines of text (with all kinds of options).
2 Copyright (C) 1988, 1991, 1992, 1993, 1994, 1995 Free Software Foundation
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.
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.
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.
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. */
22 #include <config.h>
24 /* Get isblank from GNU libc. */
25 #define _GNU_SOURCE
27 #include <sys/types.h>
28 #include <signal.h>
29 #include <stdio.h>
30 #include "system.h"
31 #include "version.h"
32 #include "long-options.h"
33 #include "error.h"
35 #ifdef _POSIX_VERSION
36 #include <limits.h>
37 #else
38 #ifndef UCHAR_MAX
39 #define UCHAR_MAX 255
40 #endif
41 #endif
42 #ifndef STDC_HEADERS
43 char *malloc ();
44 char *realloc ();
45 void free ();
46 #endif
48 static void usage ();
50 /* Undefine, to avoid warning about redefinition on some systems. */
51 #undef min
52 #define min(a, b) ((a) < (b) ? (a) : (b))
54 #define UCHAR_LIM (UCHAR_MAX + 1)
55 #define UCHAR(c) ((unsigned char) (c))
57 #ifndef DEFAULT_TMPDIR
58 #define DEFAULT_TMPDIR "/tmp"
59 #endif
61 /* The kind of blanks for '-b' to skip in various options. */
62 enum blanktype { bl_start, bl_end, bl_both };
64 /* The name this program was run with. */
65 char *program_name;
67 /* Table of digits. */
68 static int digits[UCHAR_LIM];
70 /* Table of white space. */
71 static int blanks[UCHAR_LIM];
73 /* Table of non-printing characters. */
74 static int nonprinting[UCHAR_LIM];
76 /* Table of non-dictionary characters (not letters, digits, or blanks). */
77 static int nondictionary[UCHAR_LIM];
79 /* Translation table folding lower case to upper. */
80 static char fold_toupper[UCHAR_LIM];
82 /* Table mapping 3-letter month names to integers.
83 Alphabetic order allows binary search. */
84 static struct month
86 char *name;
87 int val;
88 } const monthtab[] =
90 {"APR", 4},
91 {"AUG", 8},
92 {"DEC", 12},
93 {"FEB", 2},
94 {"JAN", 1},
95 {"JUL", 7},
96 {"JUN", 6},
97 {"MAR", 3},
98 {"MAY", 5},
99 {"NOV", 11},
100 {"OCT", 10},
101 {"SEP", 9}
104 /* During the merge phase, the number of files to merge at once. */
105 #define NMERGE 16
107 /* Initial buffer size for in core sorting. Will not grow unless a
108 line longer than this is seen. */
109 static int sortalloc = 512 * 1024;
111 /* Initial buffer size for in core merge buffers. Bear in mind that
112 up to NMERGE * mergealloc bytes may be allocated for merge buffers. */
113 static int mergealloc = 16 * 1024;
115 /* Guess of average line length. */
116 static int linelength = 30;
118 /* Maximum number of elements for the array(s) of struct line's, in bytes. */
119 #define LINEALLOC (256 * 1024)
121 /* Prefix for temporary file names. */
122 static char *temp_file_prefix;
124 /* Flag to reverse the order of all comparisons. */
125 static int reverse;
127 /* Flag for stable sort. This turns off the last ditch bytewise
128 comparison of lines, and instead leaves lines in the same order
129 they were read if all keys compare equal. */
130 static int stable;
132 /* Tab character separating fields. If NUL, then fields are separated
133 by the empty string between a non-whitespace character and a whitespace
134 character. */
135 static char tab;
137 /* Flag to remove consecutive duplicate lines from the output.
138 Only the last of a sequence of equal lines will be output. */
139 static int unique;
141 /* Nonzero if any of the input files are the standard input. */
142 static int have_read_stdin;
144 /* Lines are held in core as counted strings. */
145 struct line
147 char *text; /* Text of the line. */
148 int length; /* Length not including final newline. */
149 char *keybeg; /* Start of first key. */
150 char *keylim; /* Limit of first key. */
153 /* Arrays of lines. */
154 struct lines
156 struct line *lines; /* Dynamically allocated array of lines. */
157 int used; /* Number of slots used. */
158 int alloc; /* Number of slots allocated. */
159 int limit; /* Max number of slots to allocate. */
162 /* Input buffers. */
163 struct buffer
165 char *buf; /* Dynamically allocated buffer. */
166 int used; /* Number of bytes used. */
167 int alloc; /* Number of bytes allocated. */
168 int left; /* Number of bytes left after line parsing. */
171 /* Lists of key field comparisons to be tried. */
172 static struct keyfield
174 int sword; /* Zero-origin 'word' to start at. */
175 int schar; /* Additional characters to skip. */
176 int skipsblanks; /* Skip leading white space at start. */
177 int eword; /* Zero-origin first word after field. */
178 int echar; /* Additional characters in field. */
179 int skipeblanks; /* Skip trailing white space at finish. */
180 int *ignore; /* Boolean array of characters to ignore. */
181 char *translate; /* Translation applied to characters. */
182 int numeric; /* Flag for numeric comparison. */
183 int month; /* Flag for comparison by month name. */
184 int reverse; /* Reverse the sense of comparison. */
185 struct keyfield *next; /* Next keyfield to try. */
186 } keyhead;
188 /* The list of temporary files. */
189 static struct tempnode
191 char *name;
192 struct tempnode *next;
193 } temphead;
195 /* Clean up any remaining temporary files. */
197 static void
198 cleanup ()
200 struct tempnode *node;
202 for (node = temphead.next; node; node = node->next)
203 unlink (node->name);
206 /* Allocate N bytes of memory dynamically, with error checking. */
208 char *
209 xmalloc (n)
210 unsigned n;
212 char *p;
214 p = malloc (n);
215 if (p == 0)
217 error (0, 0, "virtual memory exhausted");
218 cleanup ();
219 exit (2);
221 return p;
224 /* Change the size of an allocated block of memory P to N bytes,
225 with error checking.
226 If P is NULL, run xmalloc.
227 If N is 0, run free and return NULL. */
229 char *
230 xrealloc (p, n)
231 char *p;
232 unsigned n;
234 if (p == 0)
235 return xmalloc (n);
236 if (n == 0)
238 free (p);
239 return 0;
241 p = realloc (p, n);
242 if (p == 0)
244 error (0, 0, "virtual memory exhausted");
245 cleanup ();
246 exit (2);
248 return p;
251 static FILE *
252 xfopen (file, how)
253 char *file, *how;
255 FILE *fp = strcmp (file, "-") ? fopen (file, how) : stdin;
257 if (fp == 0)
259 error (0, errno, "%s", file);
260 cleanup ();
261 exit (2);
263 if (fp == stdin)
264 have_read_stdin = 1;
265 return fp;
268 static void
269 xfclose (fp)
270 FILE *fp;
272 if (fp == stdin)
274 /* Allow reading stdin from tty more than once. */
275 if (feof (fp))
276 clearerr (fp);
278 else if (fp == stdout)
280 if (fflush (fp) != 0)
282 error (0, errno, "flushing file");
283 cleanup ();
284 exit (2);
287 else
289 if (fclose (fp) != 0)
291 error (0, errno, "error closing file");
292 cleanup ();
293 exit (2);
298 static void
299 xfwrite (buf, size, nelem, fp)
300 char *buf;
301 int size, nelem;
302 FILE *fp;
304 if (fwrite (buf, size, nelem, fp) != nelem)
306 error (0, errno, "write error");
307 cleanup ();
308 exit (2);
312 /* Return a name for a temporary file. */
314 static char *
315 tempname ()
317 static int seq;
318 int len = strlen (temp_file_prefix);
319 char *name = xmalloc (len + 16);
320 struct tempnode *node =
321 (struct tempnode *) xmalloc (sizeof (struct tempnode));
323 sprintf (name,
324 "%s%ssort%5.5d%5.5d",
325 temp_file_prefix,
326 (len && temp_file_prefix[len - 1] != '/') ? "/" : "",
327 (unsigned int) getpid () & 0xffff, ++seq);
328 node->name = name;
329 node->next = temphead.next;
330 temphead.next = node;
331 return name;
334 /* Search through the list of temporary files for NAME;
335 remove it if it is found on the list. */
337 static void
338 zaptemp (name)
339 char *name;
341 struct tempnode *node, *temp;
343 for (node = &temphead; node->next; node = node->next)
344 if (!strcmp (name, node->next->name))
345 break;
346 if (node->next)
348 temp = node->next;
349 unlink (temp->name);
350 free (temp->name);
351 node->next = temp->next;
352 free ((char *) temp);
356 /* Initialize the character class tables. */
358 static void
359 inittables ()
361 int i;
363 for (i = 0; i < UCHAR_LIM; ++i)
365 if (ISBLANK (i))
366 blanks[i] = 1;
367 if (ISDIGIT (i))
368 digits[i] = 1;
369 if (!ISPRINT (i))
370 nonprinting[i] = 1;
371 if (!ISALNUM (i) && !ISBLANK (i))
372 nondictionary[i] = 1;
373 if (ISLOWER (i))
374 fold_toupper[i] = toupper (i);
375 else
376 fold_toupper[i] = i;
380 /* Initialize BUF, allocating ALLOC bytes initially. */
382 static void
383 initbuf (buf, alloc)
384 struct buffer *buf;
385 int alloc;
387 buf->alloc = alloc;
388 buf->buf = xmalloc (buf->alloc);
389 buf->used = buf->left = 0;
392 /* Fill BUF reading from FP, moving buf->left bytes from the end
393 of buf->buf to the beginning first. If EOF is reached and the
394 file wasn't terminated by a newline, supply one. Return a count
395 of bytes buffered. */
397 static int
398 fillbuf (buf, fp)
399 struct buffer *buf;
400 FILE *fp;
402 int cc;
404 memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left);
405 buf->used = buf->left;
407 while (!feof (fp) && (buf->used == 0 || !memchr (buf->buf, '\n', buf->used)))
409 if (buf->used == buf->alloc)
411 buf->alloc *= 2;
412 buf->buf = xrealloc (buf->buf, buf->alloc);
414 cc = fread (buf->buf + buf->used, 1, buf->alloc - buf->used, fp);
415 if (ferror (fp))
417 error (0, errno, "read error");
418 cleanup ();
419 exit (2);
421 buf->used += cc;
424 if (feof (fp) && buf->used && buf->buf[buf->used - 1] != '\n')
426 if (buf->used == buf->alloc)
428 buf->alloc *= 2;
429 buf->buf = xrealloc (buf->buf, buf->alloc);
431 buf->buf[buf->used++] = '\n';
434 return buf->used;
437 /* Initialize LINES, allocating space for ALLOC lines initially.
438 LIMIT is the maximum possible number of lines to allocate space
439 for, ever. */
441 static void
442 initlines (lines, alloc, limit)
443 struct lines *lines;
444 int alloc;
445 int limit;
447 lines->alloc = alloc;
448 lines->lines = (struct line *) xmalloc (lines->alloc * sizeof (struct line));
449 lines->used = 0;
450 lines->limit = limit;
453 /* Return a pointer to the first character of the field specified
454 by KEY in LINE. */
456 static char *
457 begfield (line, key)
458 struct line *line;
459 struct keyfield *key;
461 register char *ptr = line->text, *lim = ptr + line->length;
462 register int sword = key->sword, schar = key->schar;
464 if (tab)
465 while (ptr < lim && sword--)
467 while (ptr < lim && *ptr != tab)
468 ++ptr;
469 if (ptr < lim)
470 ++ptr;
472 else
473 while (ptr < lim && sword--)
475 while (ptr < lim && blanks[UCHAR (*ptr)])
476 ++ptr;
477 while (ptr < lim && !blanks[UCHAR (*ptr)])
478 ++ptr;
481 if (key->skipsblanks)
482 while (ptr < lim && blanks[UCHAR (*ptr)])
483 ++ptr;
485 while (ptr < lim && schar--)
486 ++ptr;
488 return ptr;
491 /* Return the limit of (a pointer to the first character after) the field
492 in LINE specified by KEY. */
494 static char *
495 limfield (line, key)
496 struct line *line;
497 struct keyfield *key;
499 register char *ptr = line->text, *lim = ptr + line->length;
500 register int eword = key->eword, echar = key->echar;
502 if (tab)
503 while (ptr < lim && eword--)
505 while (ptr < lim && *ptr != tab)
506 ++ptr;
507 if (ptr < lim && (eword || key->skipeblanks))
508 ++ptr;
510 else
511 while (ptr < lim && eword--)
513 while (ptr < lim && blanks[UCHAR (*ptr)])
514 ++ptr;
515 while (ptr < lim && !blanks[UCHAR (*ptr)])
516 ++ptr;
519 if (key->skipeblanks)
520 while (ptr < lim && blanks[UCHAR (*ptr)])
521 ++ptr;
523 while (ptr < lim && echar--)
524 ++ptr;
526 return ptr;
529 /* Find the lines in BUF, storing pointers and lengths in LINES.
530 Also replace newlines with NULs. */
532 static void
533 findlines (buf, lines)
534 struct buffer *buf;
535 struct lines *lines;
537 register char *beg = buf->buf, *lim = buf->buf + buf->used, *ptr;
538 struct keyfield *key = keyhead.next;
540 lines->used = 0;
542 while (beg < lim && (ptr = memchr (beg, '\n', lim - beg))
543 && lines->used < lines->limit)
545 /* There are various places in the code that rely on a NUL
546 being at the end of in-core lines; NULs inside the lines
547 will not cause trouble, though. */
548 *ptr = '\0';
550 if (lines->used == lines->alloc)
552 lines->alloc *= 2;
553 lines->lines = (struct line *)
554 xrealloc ((char *) lines->lines,
555 lines->alloc * sizeof (struct line));
558 lines->lines[lines->used].text = beg;
559 lines->lines[lines->used].length = ptr - beg;
561 /* Precompute the position of the first key for efficiency. */
562 if (key)
564 if (key->eword >= 0)
565 lines->lines[lines->used].keylim =
566 limfield (&lines->lines[lines->used], key);
567 else
568 lines->lines[lines->used].keylim = ptr;
570 if (key->sword >= 0)
571 lines->lines[lines->used].keybeg =
572 begfield (&lines->lines[lines->used], key);
573 else
575 if (key->skipsblanks)
576 while (blanks[UCHAR (*beg)])
577 ++beg;
578 lines->lines[lines->used].keybeg = beg;
581 else
583 lines->lines[lines->used].keybeg = 0;
584 lines->lines[lines->used].keylim = 0;
587 ++lines->used;
588 beg = ptr + 1;
591 buf->left = lim - beg;
594 /* Compare strings A and B containing decimal fractions < 1. Each string
595 should begin with a decimal point followed immediately by the digits
596 of the fraction. Strings not of this form are considered to be zero. */
598 static int
599 fraccompare (a, b)
600 register char *a, *b;
602 register tmpa = UCHAR (*a), tmpb = UCHAR (*b);
604 if (tmpa == '.' && tmpb == '.')
607 tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
608 while (tmpa == tmpb && digits[tmpa]);
609 if (digits[tmpa] && digits[tmpb])
610 return tmpa - tmpb;
611 if (digits[tmpa])
613 while (tmpa == '0')
614 tmpa = UCHAR (*++a);
615 if (digits[tmpa])
616 return 1;
617 return 0;
619 if (digits[tmpb])
621 while (tmpb == '0')
622 tmpb = UCHAR (*++b);
623 if (digits[tmpb])
624 return -1;
625 return 0;
627 return 0;
629 else if (tmpa == '.')
632 tmpa = UCHAR (*++a);
633 while (tmpa == '0');
634 if (digits[tmpa])
635 return 1;
636 return 0;
638 else if (tmpb == '.')
641 tmpb = UCHAR (*++b);
642 while (tmpb == '0');
643 if (digits[tmpb])
644 return -1;
645 return 0;
647 return 0;
650 /* Compare strings A and B as numbers without explicitly converting them to
651 machine numbers. Comparatively slow for short strings, but asymptotically
652 hideously fast. */
654 static int
655 numcompare (a, b)
656 register char *a, *b;
658 register int tmpa, tmpb, loga, logb, tmp;
660 tmpa = UCHAR (*a), tmpb = UCHAR (*b);
662 while (blanks[tmpa])
663 tmpa = UCHAR (*++a);
664 while (blanks[tmpb])
665 tmpb = UCHAR (*++b);
667 if (tmpa == '-')
669 tmpa = UCHAR (*++a);
670 if (tmpb != '-')
672 if (digits[tmpa] && digits[tmpb])
673 return -1;
674 return 0;
676 tmpb = UCHAR (*++b);
678 while (tmpa == '0')
679 tmpa = UCHAR (*++a);
680 while (tmpb == '0')
681 tmpb = UCHAR (*++b);
683 while (tmpa == tmpb && digits[tmpa])
684 tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
686 if ((tmpa == '.' && !digits[tmpb]) || (tmpb == '.' && !digits[tmpa]))
687 return -fraccompare (a, b);
689 if (digits[tmpa])
690 for (loga = 1; digits[UCHAR (*++a)]; ++loga)
692 else
693 loga = 0;
695 if (digits[tmpb])
696 for (logb = 1; digits[UCHAR (*++b)]; ++logb)
698 else
699 logb = 0;
701 if ((tmp = logb - loga) != 0)
702 return tmp;
704 if (!loga)
705 return 0;
707 return tmpb - tmpa;
709 else if (tmpb == '-')
711 if (digits[UCHAR (tmpa)] && digits[UCHAR (*++b)])
712 return 1;
713 return 0;
715 else
717 while (tmpa == '0')
718 tmpa = UCHAR (*++a);
719 while (tmpb == '0')
720 tmpb = UCHAR (*++b);
722 while (tmpa == tmpb && digits[tmpa])
723 tmpa = UCHAR (*++a), tmpb = UCHAR (*++b);
725 if ((tmpa == '.' && !digits[tmpb]) || (tmpb == '.' && !digits[tmpa]))
726 return fraccompare (a, b);
728 if (digits[tmpa])
729 for (loga = 1; digits[UCHAR (*++a)]; ++loga)
731 else
732 loga = 0;
734 if (digits[tmpb])
735 for (logb = 1; digits[UCHAR (*++b)]; ++logb)
737 else
738 logb = 0;
740 if ((tmp = loga - logb) != 0)
741 return tmp;
743 if (!loga)
744 return 0;
746 return tmpa - tmpb;
750 /* Return an integer <= 12 associated with month name S with length LEN,
751 0 if the name in S is not recognized. */
753 static int
754 getmonth (s, len)
755 char *s;
756 int len;
758 char month[4];
759 register int i, lo = 0, hi = 12;
761 while (len > 0 && blanks[UCHAR(*s)])
762 ++s, --len;
764 if (len < 3)
765 return 0;
767 for (i = 0; i < 3; ++i)
768 month[i] = fold_toupper[UCHAR (s[i])];
769 month[3] = '\0';
771 while (hi - lo > 1)
772 if (strcmp (month, monthtab[(lo + hi) / 2].name) < 0)
773 hi = (lo + hi) / 2;
774 else
775 lo = (lo + hi) / 2;
776 if (!strcmp (month, monthtab[lo].name))
777 return monthtab[lo].val;
778 return 0;
781 /* Compare two lines A and B trying every key in sequence until there
782 are no more keys or a difference is found. */
784 static int
785 keycompare (a, b)
786 struct line *a, *b;
788 register char *texta, *textb, *lima, *limb, *translate;
789 register int *ignore;
790 struct keyfield *key;
791 int diff = 0, iter = 0, lena, lenb;
793 for (key = keyhead.next; key; key = key->next, ++iter)
795 ignore = key->ignore;
796 translate = key->translate;
798 /* Find the beginning and limit of each field. */
799 if (iter || a->keybeg == NULL || b->keybeg == NULL)
801 if (key->eword >= 0)
802 lima = limfield (a, key), limb = limfield (b, key);
803 else
804 lima = a->text + a->length, limb = b->text + b->length;
806 if (key->sword >= 0)
807 texta = begfield (a, key), textb = begfield (b, key);
808 else
810 texta = a->text, textb = b->text;
811 if (key->skipsblanks)
813 while (texta < lima && blanks[UCHAR (*texta)])
814 ++texta;
815 while (textb < limb && blanks[UCHAR (*textb)])
816 ++textb;
820 else
822 /* For the first iteration only, the key positions have
823 been precomputed for us. */
824 texta = a->keybeg, lima = a->keylim;
825 textb = b->keybeg, limb = b->keylim;
828 /* Find the lengths. */
829 lena = lima - texta, lenb = limb - textb;
830 if (lena < 0)
831 lena = 0;
832 if (lenb < 0)
833 lenb = 0;
835 /* Actually compare the fields. */
836 if (key->numeric)
838 if (*lima || *limb)
840 char savea = *lima, saveb = *limb;
842 *lima = *limb = '\0';
843 diff = numcompare (texta, textb);
844 *lima = savea, *limb = saveb;
846 else
847 diff = numcompare (texta, textb);
849 if (diff)
850 return key->reverse ? -diff : diff;
851 continue;
853 else if (key->month)
855 diff = getmonth (texta, lena) - getmonth (textb, lenb);
856 if (diff)
857 return key->reverse ? -diff : diff;
858 continue;
860 else if (ignore && translate)
861 while (texta < lima && textb < limb)
863 while (texta < lima && ignore[UCHAR (*texta)])
864 ++texta;
865 while (textb < limb && ignore[UCHAR (*textb)])
866 ++textb;
867 if (texta < lima && textb < limb &&
868 translate[UCHAR (*texta++)] != translate[UCHAR (*textb++)])
870 diff = translate[UCHAR (*--texta)] - translate[UCHAR (*--textb)];
871 break;
873 else if (texta == lima && textb < limb) diff = -1;
874 else if (texta < lima && textb == limb) diff = 1;
876 else if (ignore)
877 while (texta < lima && textb < limb)
879 while (texta < lima && ignore[UCHAR (*texta)])
880 ++texta;
881 while (textb < limb && ignore[UCHAR (*textb)])
882 ++textb;
883 if (texta < lima && textb < limb && *texta++ != *textb++)
885 diff = *--texta - *--textb;
886 break;
888 else if (texta == lima && textb < limb) diff = -1;
889 else if (texta < lima && textb == limb) diff = 1;
891 else if (translate)
892 while (texta < lima && textb < limb)
894 if (translate[UCHAR (*texta++)] != translate[UCHAR (*textb++)])
896 diff = translate[UCHAR (*--texta)] - translate[UCHAR (*--textb)];
897 break;
900 else
901 diff = memcmp (texta, textb, min (lena, lenb));
903 if (diff)
904 return key->reverse ? -diff : diff;
905 if ((diff = lena - lenb) != 0)
906 return key->reverse ? -diff : diff;
909 return 0;
912 /* Compare two lines A and B, returning negative, zero, or positive
913 depending on whether A compares less than, equal to, or greater than B. */
915 static int
916 compare (a, b)
917 register struct line *a, *b;
919 int diff, tmpa, tmpb, mini;
921 /* First try to compare on the specified keys (if any).
922 The only two cases with no key at all are unadorned sort,
923 and unadorned sort -r. */
924 if (keyhead.next)
926 diff = keycompare (a, b);
927 if (diff != 0)
928 return diff;
929 if (unique || stable)
930 return 0;
933 /* If the keys all compare equal (or no keys were specified)
934 fall through to the default byte-by-byte comparison. */
935 tmpa = a->length, tmpb = b->length;
936 mini = min (tmpa, tmpb);
937 if (mini == 0)
938 diff = tmpa - tmpb;
939 else
941 char *ap = a->text, *bp = b->text;
943 diff = UCHAR (*ap) - UCHAR (*bp);
944 if (diff == 0)
946 diff = memcmp (ap, bp, mini);
947 if (diff == 0)
948 diff = tmpa - tmpb;
952 return reverse ? -diff : diff;
955 /* Check that the lines read from the given FP come in order. Return
956 1 if they do and 0 if there is a disorder. */
958 static int
959 checkfp (fp)
960 FILE *fp;
962 struct buffer buf; /* Input buffer. */
963 struct lines lines; /* Lines scanned from the buffer. */
964 struct line *prev_line; /* Pointer to previous line. */
965 struct line temp; /* Copy of previous line. */
966 int cc; /* Character count. */
967 int cmp; /* Result of calling compare. */
968 int alloc, i, success = 1;
970 initbuf (&buf, mergealloc);
971 initlines (&lines, mergealloc / linelength + 1,
972 LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
973 alloc = linelength;
974 temp.text = xmalloc (alloc);
976 cc = fillbuf (&buf, fp);
977 findlines (&buf, &lines);
979 if (cc)
982 /* Compare each line in the buffer with its successor. */
983 for (i = 0; i < lines.used - 1; ++i)
985 cmp = compare (&lines.lines[i], &lines.lines[i + 1]);
986 if ((unique && cmp >= 0) || (cmp > 0))
988 success = 0;
989 goto finish;
993 /* Save the last line of the buffer and refill the buffer. */
994 prev_line = lines.lines + lines.used - 1;
995 if (prev_line->length > alloc)
997 while (prev_line->length + 1 > alloc)
998 alloc *= 2;
999 temp.text = xrealloc (temp.text, alloc);
1001 memcpy (temp.text, prev_line->text, prev_line->length + 1);
1002 temp.length = prev_line->length;
1003 temp.keybeg = temp.text + (prev_line->keybeg - prev_line->text);
1004 temp.keylim = temp.text + (prev_line->keylim - prev_line->text);
1006 cc = fillbuf (&buf, fp);
1007 if (cc)
1009 findlines (&buf, &lines);
1010 /* Make sure the line saved from the old buffer contents is
1011 less than or equal to the first line of the new buffer. */
1012 cmp = compare (&temp, &lines.lines[0]);
1013 if ((unique && cmp >= 0) || (cmp > 0))
1015 success = 0;
1016 break;
1020 while (cc);
1022 finish:
1023 xfclose (fp);
1024 free (buf.buf);
1025 free ((char *) lines.lines);
1026 free (temp.text);
1027 return success;
1030 /* Merge lines from FPS onto OFP. NFPS cannot be greater than NMERGE.
1031 Close FPS before returning. */
1033 static void
1034 mergefps (fps, nfps, ofp)
1035 FILE *fps[], *ofp;
1036 register int nfps;
1038 struct buffer buffer[NMERGE]; /* Input buffers for each file. */
1039 struct lines lines[NMERGE]; /* Line tables for each buffer. */
1040 struct line saved; /* Saved line for unique check. */
1041 int savedflag = 0; /* True if there is a saved line. */
1042 int savealloc; /* Size allocated for the saved line. */
1043 int cur[NMERGE]; /* Current line in each line table. */
1044 int ord[NMERGE]; /* Table representing a permutation of fps,
1045 such that lines[ord[0]].lines[cur[ord[0]]]
1046 is the smallest line and will be next
1047 output. */
1048 register int i, j, t;
1050 /* Allocate space for a saved line if necessary. */
1051 if (unique)
1053 savealloc = linelength;
1054 saved.text = xmalloc (savealloc);
1057 /* Read initial lines from each input file. */
1058 for (i = 0; i < nfps; ++i)
1060 initbuf (&buffer[i], mergealloc);
1061 /* If a file is empty, eliminate it from future consideration. */
1062 while (i < nfps && !fillbuf (&buffer[i], fps[i]))
1064 xfclose (fps[i]);
1065 --nfps;
1066 for (j = i; j < nfps; ++j)
1067 fps[j] = fps[j + 1];
1069 if (i == nfps)
1070 free (buffer[i].buf);
1071 else
1073 initlines (&lines[i], mergealloc / linelength + 1,
1074 LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
1075 findlines (&buffer[i], &lines[i]);
1076 cur[i] = 0;
1080 /* Set up the ord table according to comparisons among input lines.
1081 Since this only reorders two items if one is strictly greater than
1082 the other, it is stable. */
1083 for (i = 0; i < nfps; ++i)
1084 ord[i] = i;
1085 for (i = 1; i < nfps; ++i)
1086 if (compare (&lines[ord[i - 1]].lines[cur[ord[i - 1]]],
1087 &lines[ord[i]].lines[cur[ord[i]]]) > 0)
1088 t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0;
1090 /* Repeatedly output the smallest line until no input remains. */
1091 while (nfps)
1093 /* If uniqified output is turned on, output only the first of
1094 an identical series of lines. */
1095 if (unique)
1097 if (savedflag && compare (&saved, &lines[ord[0]].lines[cur[ord[0]]]))
1099 xfwrite (saved.text, 1, saved.length, ofp);
1100 putc ('\n', ofp);
1101 savedflag = 0;
1103 if (!savedflag)
1105 if (savealloc < lines[ord[0]].lines[cur[ord[0]]].length + 1)
1107 while (savealloc < lines[ord[0]].lines[cur[ord[0]]].length + 1)
1108 savealloc *= 2;
1109 saved.text = xrealloc (saved.text, savealloc);
1111 saved.length = lines[ord[0]].lines[cur[ord[0]]].length;
1112 memcpy (saved.text, lines[ord[0]].lines[cur[ord[0]]].text,
1113 saved.length + 1);
1114 if (lines[ord[0]].lines[cur[ord[0]]].keybeg != NULL)
1116 saved.keybeg = saved.text +
1117 (lines[ord[0]].lines[cur[ord[0]]].keybeg
1118 - lines[ord[0]].lines[cur[ord[0]]].text);
1120 if (lines[ord[0]].lines[cur[ord[0]]].keylim != NULL)
1122 saved.keylim = saved.text +
1123 (lines[ord[0]].lines[cur[ord[0]]].keylim
1124 - lines[ord[0]].lines[cur[ord[0]]].text);
1126 savedflag = 1;
1129 else
1131 xfwrite (lines[ord[0]].lines[cur[ord[0]]].text, 1,
1132 lines[ord[0]].lines[cur[ord[0]]].length, ofp);
1133 putc ('\n', ofp);
1136 /* Check if we need to read more lines into core. */
1137 if (++cur[ord[0]] == lines[ord[0]].used)
1138 if (fillbuf (&buffer[ord[0]], fps[ord[0]]))
1140 findlines (&buffer[ord[0]], &lines[ord[0]]);
1141 cur[ord[0]] = 0;
1143 else
1145 /* We reached EOF on fps[ord[0]]. */
1146 for (i = 1; i < nfps; ++i)
1147 if (ord[i] > ord[0])
1148 --ord[i];
1149 --nfps;
1150 xfclose (fps[ord[0]]);
1151 free (buffer[ord[0]].buf);
1152 free ((char *) lines[ord[0]].lines);
1153 for (i = ord[0]; i < nfps; ++i)
1155 fps[i] = fps[i + 1];
1156 buffer[i] = buffer[i + 1];
1157 lines[i] = lines[i + 1];
1158 cur[i] = cur[i + 1];
1160 for (i = 0; i < nfps; ++i)
1161 ord[i] = ord[i + 1];
1162 continue;
1165 /* The new line just read in may be larger than other lines
1166 already in core; push it back in the queue until we encounter
1167 a line larger than it. */
1168 for (i = 1; i < nfps; ++i)
1170 t = compare (&lines[ord[0]].lines[cur[ord[0]]],
1171 &lines[ord[i]].lines[cur[ord[i]]]);
1172 if (!t)
1173 t = ord[0] - ord[i];
1174 if (t < 0)
1175 break;
1177 t = ord[0];
1178 for (j = 1; j < i; ++j)
1179 ord[j - 1] = ord[j];
1180 ord[i - 1] = t;
1183 if (unique && savedflag)
1185 xfwrite (saved.text, 1, saved.length, ofp);
1186 putc ('\n', ofp);
1187 free (saved.text);
1191 /* Sort the array LINES with NLINES members, using TEMP for temporary space. */
1193 static void
1194 sortlines (lines, nlines, temp)
1195 struct line *lines, *temp;
1196 int nlines;
1198 register struct line *lo, *hi, *t;
1199 register int nlo, nhi;
1201 if (nlines == 2)
1203 if (compare (&lines[0], &lines[1]) > 0)
1204 *temp = lines[0], lines[0] = lines[1], lines[1] = *temp;
1205 return;
1208 nlo = nlines / 2;
1209 lo = lines;
1210 nhi = nlines - nlo;
1211 hi = lines + nlo;
1213 if (nlo > 1)
1214 sortlines (lo, nlo, temp);
1216 if (nhi > 1)
1217 sortlines (hi, nhi, temp);
1219 t = temp;
1221 while (nlo && nhi)
1222 if (compare (lo, hi) <= 0)
1223 *t++ = *lo++, --nlo;
1224 else
1225 *t++ = *hi++, --nhi;
1226 while (nlo--)
1227 *t++ = *lo++;
1229 for (lo = lines, nlo = nlines - nhi, t = temp; nlo; --nlo)
1230 *lo++ = *t++;
1233 /* Check that each of the NFILES FILES is ordered.
1234 Return a count of disordered files. */
1236 static int
1237 check (files, nfiles)
1238 char *files[];
1239 int nfiles;
1241 int i, disorders = 0;
1242 FILE *fp;
1244 for (i = 0; i < nfiles; ++i)
1246 fp = xfopen (files[i], "r");
1247 if (!checkfp (fp))
1249 printf ("%s: disorder on %s\n", program_name, files[i]);
1250 ++disorders;
1253 return disorders;
1256 /* Merge NFILES FILES onto OFP. */
1258 static void
1259 merge (files, nfiles, ofp)
1260 char *files[];
1261 int nfiles;
1262 FILE *ofp;
1264 int i, j, t;
1265 char *temp;
1266 FILE *fps[NMERGE], *tfp;
1268 while (nfiles > NMERGE)
1270 t = 0;
1271 for (i = 0; i < nfiles / NMERGE; ++i)
1273 for (j = 0; j < NMERGE; ++j)
1274 fps[j] = xfopen (files[i * NMERGE + j], "r");
1275 tfp = xfopen (temp = tempname (), "w");
1276 mergefps (fps, NMERGE, tfp);
1277 xfclose (tfp);
1278 for (j = 0; j < NMERGE; ++j)
1279 zaptemp (files[i * NMERGE + j]);
1280 files[t++] = temp;
1282 for (j = 0; j < nfiles % NMERGE; ++j)
1283 fps[j] = xfopen (files[i * NMERGE + j], "r");
1284 tfp = xfopen (temp = tempname (), "w");
1285 mergefps (fps, nfiles % NMERGE, tfp);
1286 xfclose (tfp);
1287 for (j = 0; j < nfiles % NMERGE; ++j)
1288 zaptemp (files[i * NMERGE + j]);
1289 files[t++] = temp;
1290 nfiles = t;
1293 for (i = 0; i < nfiles; ++i)
1294 fps[i] = xfopen (files[i], "r");
1295 mergefps (fps, i, ofp);
1296 for (i = 0; i < nfiles; ++i)
1297 zaptemp (files[i]);
1300 /* Sort NFILES FILES onto OFP. */
1302 static void
1303 sort (files, nfiles, ofp)
1304 char **files;
1305 int nfiles;
1306 FILE *ofp;
1308 struct buffer buf;
1309 struct lines lines;
1310 struct line *tmp;
1311 int i, ntmp;
1312 FILE *fp, *tfp;
1313 struct tempnode *node;
1314 int ntemp = 0;
1315 char **tempfiles;
1317 initbuf (&buf, sortalloc);
1318 initlines (&lines, sortalloc / linelength + 1,
1319 LINEALLOC / sizeof (struct line));
1320 ntmp = lines.alloc;
1321 tmp = (struct line *) xmalloc (ntmp * sizeof (struct line));
1323 while (nfiles--)
1325 fp = xfopen (*files++, "r");
1326 while (fillbuf (&buf, fp))
1328 findlines (&buf, &lines);
1329 if (lines.used > ntmp)
1331 while (lines.used > ntmp)
1332 ntmp *= 2;
1333 tmp = (struct line *)
1334 xrealloc ((char *) tmp, ntmp * sizeof (struct line));
1336 sortlines (lines.lines, lines.used, tmp);
1337 if (feof (fp) && !nfiles && !ntemp && !buf.left)
1338 tfp = ofp;
1339 else
1341 ++ntemp;
1342 tfp = xfopen (tempname (), "w");
1344 for (i = 0; i < lines.used; ++i)
1345 if (!unique || i == 0
1346 || compare (&lines.lines[i], &lines.lines[i - 1]))
1348 xfwrite (lines.lines[i].text, 1, lines.lines[i].length, tfp);
1349 putc ('\n', tfp);
1351 if (tfp != ofp)
1352 xfclose (tfp);
1354 xfclose (fp);
1357 free (buf.buf);
1358 free ((char *) lines.lines);
1359 free ((char *) tmp);
1361 if (ntemp)
1363 tempfiles = (char **) xmalloc (ntemp * sizeof (char *));
1364 i = ntemp;
1365 for (node = temphead.next; i > 0; node = node->next)
1366 tempfiles[--i] = node->name;
1367 merge (tempfiles, ntemp, ofp);
1368 free ((char *) tempfiles);
1372 /* Insert key KEY at the end of the list (`keyhead'). */
1374 static void
1375 insertkey (key)
1376 struct keyfield *key;
1378 struct keyfield *k = &keyhead;
1380 while (k->next)
1381 k = k->next;
1382 k->next = key;
1383 key->next = NULL;
1386 static void
1387 badfieldspec (s)
1388 char *s;
1390 error (2, 0, "invalid field specification `%s'", s);
1393 /* Handle interrupts and hangups. */
1395 static void
1396 sighandler (sig)
1397 int sig;
1399 #ifdef _POSIX_VERSION
1400 struct sigaction sigact;
1402 sigact.sa_handler = SIG_DFL;
1403 sigemptyset (&sigact.sa_mask);
1404 sigact.sa_flags = 0;
1405 sigaction (sig, &sigact, NULL);
1406 #else /* !_POSIX_VERSION */
1407 signal (sig, SIG_DFL);
1408 #endif /* _POSIX_VERSION */
1409 cleanup ();
1410 kill (getpid (), sig);
1413 /* Set the ordering options for KEY specified in S.
1414 Return the address of the first character in S that
1415 is not a valid ordering option.
1416 BLANKTYPE is the kind of blanks that 'b' should skip. */
1418 static char *
1419 set_ordering (s, key, blanktype)
1420 register char *s;
1421 struct keyfield *key;
1422 enum blanktype blanktype;
1424 while (*s)
1426 switch (*s)
1428 case 'b':
1429 if (blanktype == bl_start || blanktype == bl_both)
1430 key->skipsblanks = 1;
1431 if (blanktype == bl_end || blanktype == bl_both)
1432 key->skipeblanks = 1;
1433 break;
1434 case 'd':
1435 key->ignore = nondictionary;
1436 break;
1437 case 'f':
1438 key->translate = fold_toupper;
1439 break;
1440 #if 0
1441 case 'g':
1442 /* Reserved for comparing floating-point numbers. */
1443 break;
1444 #endif
1445 case 'i':
1446 key->ignore = nonprinting;
1447 break;
1448 case 'M':
1449 key->month = 1;
1450 break;
1451 case 'n':
1452 key->numeric = 1;
1453 if (blanktype == bl_start || blanktype == bl_both)
1454 key->skipsblanks = 1;
1455 if (blanktype == bl_end || blanktype == bl_both)
1456 key->skipeblanks = 1;
1457 break;
1458 case 'r':
1459 key->reverse = 1;
1460 break;
1461 default:
1462 return s;
1464 ++s;
1466 return s;
1469 void
1470 main (argc, argv)
1471 int argc;
1472 char *argv[];
1474 struct keyfield *key = NULL, gkey;
1475 char *s;
1476 int i, t, t2;
1477 int checkonly = 0, mergeonly = 0, nfiles = 0;
1478 char *minus = "-", *outfile = minus, **files, *tmp;
1479 FILE *ofp;
1480 #ifdef _POSIX_VERSION
1481 struct sigaction oldact, newact;
1482 #endif /* _POSIX_VERSION */
1484 program_name = argv[0];
1486 parse_long_options (argc, argv, "sort", version_string, usage);
1488 have_read_stdin = 0;
1489 inittables ();
1491 temp_file_prefix = getenv ("TMPDIR");
1492 if (temp_file_prefix == NULL)
1493 temp_file_prefix = DEFAULT_TMPDIR;
1495 #ifdef _POSIX_VERSION
1496 newact.sa_handler = sighandler;
1497 sigemptyset (&newact.sa_mask);
1498 newact.sa_flags = 0;
1500 sigaction (SIGINT, NULL, &oldact);
1501 if (oldact.sa_handler != SIG_IGN)
1502 sigaction (SIGINT, &newact, NULL);
1503 sigaction (SIGHUP, NULL, &oldact);
1504 if (oldact.sa_handler != SIG_IGN)
1505 sigaction (SIGHUP, &newact, NULL);
1506 sigaction (SIGPIPE, NULL, &oldact);
1507 if (oldact.sa_handler != SIG_IGN)
1508 sigaction (SIGPIPE, &newact, NULL);
1509 sigaction (SIGTERM, NULL, &oldact);
1510 if (oldact.sa_handler != SIG_IGN)
1511 sigaction (SIGTERM, &newact, NULL);
1512 #else /* !_POSIX_VERSION */
1513 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1514 signal (SIGINT, sighandler);
1515 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1516 signal (SIGHUP, sighandler);
1517 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
1518 signal (SIGPIPE, sighandler);
1519 if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
1520 signal (SIGTERM, sighandler);
1521 #endif /* !_POSIX_VERSION */
1523 gkey.sword = gkey.eword = -1;
1524 gkey.ignore = NULL;
1525 gkey.translate = NULL;
1526 gkey.numeric = gkey.month = gkey.reverse = 0;
1527 gkey.skipsblanks = gkey.skipeblanks = 0;
1529 files = (char **) xmalloc (sizeof (char *) * argc);
1531 for (i = 1; i < argc; ++i)
1533 if (argv[i][0] == '+')
1535 if (key)
1536 insertkey (key);
1537 key = (struct keyfield *) xmalloc (sizeof (struct keyfield));
1538 key->eword = -1;
1539 key->ignore = NULL;
1540 key->translate = NULL;
1541 key->skipsblanks = key->skipeblanks = 0;
1542 key->numeric = key->month = key->reverse = 0;
1543 s = argv[i] + 1;
1544 if (!digits[UCHAR (*s)])
1545 badfieldspec (argv[i]);
1546 for (t = 0; digits[UCHAR (*s)]; ++s)
1547 t = 10 * t + *s - '0';
1548 t2 = 0;
1549 if (*s == '.')
1550 for (++s; digits[UCHAR (*s)]; ++s)
1551 t2 = 10 * t2 + *s - '0';
1552 if (t2 || t)
1554 key->sword = t;
1555 key->schar = t2;
1557 else
1558 key->sword = -1;
1559 s = set_ordering (s, key, bl_start);
1560 if (*s)
1561 badfieldspec (argv[i]);
1563 else if (argv[i][0] == '-' && argv[i][1])
1565 s = argv[i] + 1;
1566 if (digits[UCHAR (*s)])
1568 if (!key)
1569 usage (2);
1570 for (t = 0; digits[UCHAR (*s)]; ++s)
1571 t = t * 10 + *s - '0';
1572 t2 = 0;
1573 if (*s == '.')
1574 for (++s; digits[UCHAR (*s)]; ++s)
1575 t2 = t2 * 10 + *s - '0';
1576 key->eword = t;
1577 key->echar = t2;
1578 s = set_ordering (s, key, bl_end);
1579 if (*s)
1580 badfieldspec (argv[i]);
1581 insertkey (key);
1582 key = NULL;
1584 else
1585 while (*s)
1587 s = set_ordering (s, &gkey, bl_both);
1588 switch (*s)
1590 case '\0':
1591 break;
1592 case 'c':
1593 checkonly = 1;
1594 break;
1595 case 'k':
1596 if (s[1])
1597 ++s;
1598 else
1600 if (i == argc - 1)
1601 error (2, 0, "option `-k' requires an argument");
1602 else
1603 s = argv[++i];
1605 if (key)
1606 insertkey (key);
1607 key = (struct keyfield *)
1608 xmalloc (sizeof (struct keyfield));
1609 key->eword = -1;
1610 key->ignore = NULL;
1611 key->translate = NULL;
1612 key->skipsblanks = key->skipeblanks = 0;
1613 key->numeric = key->month = key->reverse = 0;
1614 /* Get POS1. */
1615 if (!digits[UCHAR (*s)])
1616 badfieldspec (argv[i]);
1617 for (t = 0; digits[UCHAR (*s)]; ++s)
1618 t = 10 * t + *s - '0';
1619 if (t)
1620 t--;
1621 t2 = 0;
1622 if (*s == '.')
1624 for (++s; digits[UCHAR (*s)]; ++s)
1625 t2 = 10 * t2 + *s - '0';
1626 if (t2)
1627 t2--;
1629 if (t2 || t)
1631 key->sword = t;
1632 key->schar = t2;
1634 else
1635 key->sword = -1;
1636 s = set_ordering (s, key, bl_start);
1637 if (*s && *s != ',')
1638 badfieldspec (argv[i]);
1639 else if (*s++)
1641 /* Get POS2. */
1642 for (t = 0; digits[UCHAR (*s)]; ++s)
1643 t = t * 10 + *s - '0';
1644 if (t)
1645 t--;
1646 t2 = 0;
1647 if (*s == '.')
1649 for (++s; digits[UCHAR (*s)]; ++s)
1650 t2 = t2 * 10 + *s - '0';
1651 if (t2)
1652 t2--;
1654 key->eword = t;
1655 key->echar = t2;
1656 s = set_ordering (s, key, bl_end);
1657 if (*s)
1658 badfieldspec (argv[i]);
1660 insertkey (key);
1661 key = NULL;
1662 goto outer;
1663 case 'm':
1664 mergeonly = 1;
1665 break;
1666 case 'o':
1667 if (s[1])
1668 outfile = s + 1;
1669 else
1671 if (i == argc - 1)
1672 error (2, 0, "option `-o' requires an argument");
1673 else
1674 outfile = argv[++i];
1676 goto outer;
1677 case 's':
1678 stable = 1;
1679 break;
1680 case 't':
1681 if (s[1])
1682 tab = *++s;
1683 else if (i < argc - 1)
1685 tab = *argv[++i];
1686 goto outer;
1688 else
1689 error (2, 0, "option `-t' requires an argument");
1690 break;
1691 case 'T':
1692 if (s[1])
1693 temp_file_prefix = ++s;
1694 else
1696 if (i < argc - 1)
1697 temp_file_prefix = argv[++i];
1698 else
1699 error (2, 0, "option `-T' requires an argument");
1701 goto outer;
1702 break;
1703 case 'u':
1704 unique = 1;
1705 break;
1706 case 'y':
1707 /* Accept and ignore e.g. -y0 for compatibility with
1708 Solaris 2. */
1709 goto outer;
1710 default:
1711 fprintf (stderr, "%s: unrecognized option `-%c'\n",
1712 argv[0], *s);
1713 usage (2);
1715 if (*s)
1716 ++s;
1719 else /* Not an option. */
1721 files[nfiles++] = argv[i];
1723 outer:;
1726 if (key)
1727 insertkey (key);
1729 /* Inheritance of global options to individual keys. */
1730 for (key = keyhead.next; key; key = key->next)
1731 if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse
1732 && !key->skipeblanks && !key->month && !key->numeric)
1734 key->ignore = gkey.ignore;
1735 key->translate = gkey.translate;
1736 key->skipsblanks = gkey.skipsblanks;
1737 key->skipeblanks = gkey.skipeblanks;
1738 key->month = gkey.month;
1739 key->numeric = gkey.numeric;
1740 key->reverse = gkey.reverse;
1743 if (!keyhead.next && (gkey.ignore || gkey.translate || gkey.skipsblanks
1744 || gkey.skipeblanks || gkey.month || gkey.numeric))
1745 insertkey (&gkey);
1746 reverse = gkey.reverse;
1748 if (nfiles == 0)
1750 nfiles = 1;
1751 files = &minus;
1754 if (checkonly)
1755 exit (check (files, nfiles) != 0);
1757 if (strcmp (outfile, "-"))
1759 struct stat outstat;
1760 if (stat (outfile, &outstat) == 0)
1762 /* The following code prevents a race condition when
1763 people use the brain dead shell programming idiom:
1764 cat file | sort -o file
1765 This feature is provided for historical compatibility,
1766 but we strongly discourage ever relying on this in
1767 new shell programs. */
1769 /* Temporarily copy each input file that might be another name
1770 for the output file. When in doubt (e.g. a pipe), copy. */
1771 for (i = 0; i < nfiles; ++i)
1773 char buf[8192];
1774 FILE *fp;
1775 int cc;
1777 if (S_ISREG (outstat.st_mode) && strcmp (outfile, files[i]))
1779 struct stat instat;
1780 if ((strcmp (files[i], "-")
1781 ? stat (files[i], &instat)
1782 : fstat (fileno (stdin), &instat)) != 0)
1784 error (0, errno, "%s", files[i]);
1785 cleanup ();
1786 exit (2);
1788 if (S_ISREG (instat.st_mode)
1789 && (instat.st_ino != outstat.st_ino
1790 || instat.st_dev != outstat.st_dev))
1792 /* We know the files are distinct. */
1793 continue;
1797 fp = xfopen (files[i], "r");
1798 tmp = tempname ();
1799 ofp = xfopen (tmp, "w");
1800 while ((cc = fread (buf, 1, sizeof buf, fp)) > 0)
1801 xfwrite (buf, 1, cc, ofp);
1802 if (ferror (fp))
1804 error (0, errno, "%s", files[i]);
1805 cleanup ();
1806 exit (2);
1808 xfclose (ofp);
1809 xfclose (fp);
1810 files[i] = tmp;
1813 ofp = xfopen (outfile, "w");
1815 else
1816 ofp = stdout;
1818 if (mergeonly)
1819 merge (files, nfiles, ofp);
1820 else
1821 sort (files, nfiles, ofp);
1822 cleanup ();
1824 /* If we wait for the implicit flush on exit, and the parent process
1825 has closed stdout (e.g., exec >&- in a shell), then the output file
1826 winds up empty. I don't understand why. This is under SunOS,
1827 Solaris, Ultrix, and Irix. This premature fflush makes the output
1828 reappear. --karl@cs.umb.edu */
1829 if (fflush (ofp) < 0)
1830 error (1, errno, "%s: write error", outfile);
1832 if (have_read_stdin && fclose (stdin) == EOF)
1833 error (1, errno, outfile);
1834 if (ferror (stdout) || fclose (stdout) == EOF)
1835 error (1, errno, "%s: write error", outfile);
1837 exit (0);
1840 static void
1841 usage (status)
1842 int status;
1844 if (status != 0)
1845 fprintf (stderr, "Try `%s --help' for more information.\n",
1846 program_name);
1847 else
1849 printf ("\
1850 Usage: %s [OPTION]... [FILE]...\n\
1852 program_name);
1853 printf ("\
1854 Write sorted concatenation of all FILE(s) to standard output.\n\
1856 +POS1 [-POS2] start a key at POS1, end it before POS2\n\
1857 -M compare (unknown) < `JAN' < ... < `DEC', imply -b\n\
1858 -T DIRECT use DIRECT for temporary files, not $TMPDIR or %s\n\
1859 -b ignore leading blanks in sort fields or keys\n\
1860 -c check if given files already sorted, do not sort\n\
1861 -d consider only [a-zA-Z0-9 ] characters in keys\n\
1862 -f fold lower case to upper case characters in keys\n\
1863 -i consider only [\\040-\\0176] characters in keys\n\
1864 -k POS1[,POS2] same as +POS1 [-POS2], but all positions counted from 1\n\
1865 -m merge already sorted files, do not sort\n\
1866 -n compare according to string numerical value, imply -b\n\
1867 -o FILE write result on FILE instead of standard output\n\
1868 -r reverse the result of comparisons\n\
1869 -s stabilize sort by disabling last resort comparison\n\
1870 -t SEP use SEParator instead of non- to whitespace transition\n\
1871 -u with -c, check for strict ordering\n\
1872 -u with -m, only output the first of an equal sequence\n\
1873 --help display this help and exit\n\
1874 --version output version information and exit\n\
1876 POS is F[.C][OPTS], where F is the field number and C the character\n\
1877 position in the field, both counted from zero. OPTS is made up of one\n\
1878 or more of Mbdfinr, this effectively disable global -Mbdfinr settings\n\
1879 for that key. If no key given, use the entire line as key. With no\n\
1880 FILE, or when FILE is -, read standard input.\n\
1882 , DEFAULT_TMPDIR);
1884 exit (status);