1 /* join - join lines of two files on a common field
2 Copyright (C) 1991-2012 Free Software Foundation, Inc.
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 3 of the License, or
7 (at your option) 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, see <http://www.gnu.org/licenses/>.
17 Written by Mike Haertel, mike@gnu.ai.mit.edu. */
22 #include <sys/types.h>
28 #include "hard-locale.h"
29 #include "linebuffer.h"
30 #include "memcasecmp.h"
37 /* The official name of this program (e.g., no 'g' prefix). */
38 #define PROGRAM_NAME "join"
40 #define AUTHORS proper_name ("Mike Haertel")
42 #define join system_join
44 #define SWAPLINES(a, b) do { \
45 struct line *tmp = a; \
50 /* An element of the list identifying which fields to print for each
54 /* File number: 0, 1, or 2. 0 means use the join field.
55 1 means use the first file argument, 2 the second. */
58 /* Field index (zero-based), specified only when FILE is 1 or 2. */
64 /* A field of a line. */
67 char *beg
; /* First character in field. */
68 size_t len
; /* The length of the field. */
71 /* A line read from an input file. */
74 struct linebuffer buf
; /* The line itself. */
75 size_t nfields
; /* Number of elements in 'fields'. */
76 size_t nfields_allocated
; /* Number of elements allocated for 'fields'. */
80 /* One or more consecutive lines read from a file that all have the
81 same join field value. */
84 size_t count
; /* Elements used in 'lines'. */
85 size_t alloc
; /* Elements allocated in 'lines'. */
89 /* The previous line read from each file. */
90 static struct line
*prevline
[2] = {NULL
, NULL
};
92 /* The number of lines read from each file. */
93 static uintmax_t line_no
[2] = {0, 0};
95 /* The input file names. */
96 static char *g_names
[2];
98 /* This provides an extra line buffer for each file. We need these if we
99 try to read two consecutive lines into the same buffer, since we don't
100 want to overwrite the previous buffer before we check order. */
101 static struct line
*spareline
[2] = {NULL
, NULL
};
103 /* True if the LC_COLLATE locale is hard. */
104 static bool hard_LC_COLLATE
;
106 /* If nonzero, print unpairable lines in file 1 or 2. */
107 static bool print_unpairables_1
, print_unpairables_2
;
109 /* If nonzero, print pairable lines. */
110 static bool print_pairables
;
112 /* If nonzero, we have seen at least one unpairable line. */
113 static bool seen_unpairable
;
115 /* If nonzero, we have warned about disorder in that file. */
116 static bool issued_disorder_warning
[2];
118 /* Empty output field filler. */
119 static char const *empty_filler
;
121 /* Whether to ensure the same number of fields are output from each line. */
122 static bool autoformat
;
123 /* The number of fields to output for each line.
124 Only significant when autoformat is true. */
125 static size_t autocount_1
;
126 static size_t autocount_2
;
128 /* Field to join on; SIZE_MAX means they haven't been determined yet. */
129 static size_t join_field_1
= SIZE_MAX
;
130 static size_t join_field_2
= SIZE_MAX
;
132 /* List of fields to print. */
133 static struct outlist outlist_head
;
135 /* Last element in 'outlist', where a new element can be added. */
136 static struct outlist
*outlist_end
= &outlist_head
;
138 /* Tab character separating fields. If negative, fields are separated
139 by any nonempty string of blanks, otherwise by exactly one
140 tab character whose value (when cast to unsigned char) equals TAB. */
143 /* If nonzero, check that the input is correctly ordered. */
153 CHECK_ORDER_OPTION
= CHAR_MAX
+ 1,
154 NOCHECK_ORDER_OPTION
,
159 static struct option
const longopts
[] =
161 {"ignore-case", no_argument
, NULL
, 'i'},
162 {"check-order", no_argument
, NULL
, CHECK_ORDER_OPTION
},
163 {"nocheck-order", no_argument
, NULL
, NOCHECK_ORDER_OPTION
},
164 {"header", no_argument
, NULL
, HEADER_LINE_OPTION
},
165 {GETOPT_HELP_OPTION_DECL
},
166 {GETOPT_VERSION_OPTION_DECL
},
170 /* Used to print non-joining lines */
171 static struct line uni_blank
;
173 /* If nonzero, ignore case when comparing join fields. */
174 static bool ignore_case
;
176 /* If nonzero, treat the first line of each file as column headers --
177 join them without checking for ordering */
178 static bool join_header_lines
;
183 if (status
!= EXIT_SUCCESS
)
188 Usage: %s [OPTION]... FILE1 FILE2\n\
192 For each pair of input lines with identical join fields, write a line to\n\
193 standard output. The default join field is the first, delimited\n\
194 by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n\
196 -a FILENUM also print unpairable lines from file FILENUM, where\n\
197 FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\
198 -e EMPTY replace missing input fields with EMPTY\n\
201 -i, --ignore-case ignore differences in case when comparing fields\n\
202 -j FIELD equivalent to '-1 FIELD -2 FIELD'\n\
203 -o FORMAT obey FORMAT while constructing output line\n\
204 -t CHAR use CHAR as input and output field separator\n\
207 -v FILENUM like -a FILENUM, but suppress joined output lines\n\
208 -1 FIELD join on this FIELD of file 1\n\
209 -2 FIELD join on this FIELD of file 2\n\
210 --check-order check that the input is correctly sorted, even\n\
211 if all input lines are pairable\n\
212 --nocheck-order do not check that the input is correctly sorted\n\
213 --header treat the first line in each file as field headers,\n\
214 print them without trying to pair them\n\
216 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
217 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
220 Unless -t CHAR is given, leading blanks separate fields and are ignored,\n\
221 else fields are separated by CHAR. Any FIELD is a field number counted\n\
222 from 1. FORMAT is one or more comma or blank separated specifications,\n\
223 each being 'FILENUM.FIELD' or '0'. Default FORMAT outputs the join field,\n\
224 the remaining fields from FILE1, the remaining fields from FILE2, all\n\
225 separated by CHAR. If FORMAT is the keyword 'auto', then the first\n\
226 line of each file determines the number of fields output for each line.\n\
228 Important: FILE1 and FILE2 must be sorted on the join fields.\n\
229 E.g., use \"sort -k 1b,1\" if 'join' has no options,\n\
230 or use \"join -t ''\" if 'sort' has no options.\n\
231 Note, comparisons honor the rules specified by 'LC_COLLATE'.\n\
232 If the input is not sorted and some lines cannot be joined, a\n\
233 warning message will be given.\n\
235 emit_ancillary_info ();
240 /* Record a field in LINE, with location FIELD and size LEN. */
243 extract_field (struct line
*line
, char *field
, size_t len
)
245 if (line
->nfields
>= line
->nfields_allocated
)
247 line
->fields
= X2NREALLOC (line
->fields
, &line
->nfields_allocated
);
249 line
->fields
[line
->nfields
].beg
= field
;
250 line
->fields
[line
->nfields
].len
= len
;
254 /* Fill in the 'fields' structure in LINE. */
257 xfields (struct line
*line
)
259 char *ptr
= line
->buf
.buffer
;
260 char const *lim
= ptr
+ line
->buf
.length
- 1;
265 if (0 <= tab
&& tab
!= '\n')
268 for (; (sep
= memchr (ptr
, tab
, lim
- ptr
)) != NULL
; ptr
= sep
+ 1)
269 extract_field (line
, ptr
, sep
- ptr
);
273 /* Skip leading blanks before the first field. */
274 while (isblank (to_uchar (*ptr
)))
281 for (sep
= ptr
+ 1; sep
!= lim
&& ! isblank (to_uchar (*sep
)); sep
++)
283 extract_field (line
, ptr
, sep
- ptr
);
286 for (ptr
= sep
+ 1; ptr
!= lim
&& isblank (to_uchar (*ptr
)); ptr
++)
292 extract_field (line
, ptr
, lim
- ptr
);
296 freeline (struct line
*line
)
302 free (line
->buf
.buffer
);
303 line
->buf
.buffer
= NULL
;
306 /* Return <0 if the join field in LINE1 compares less than the one in LINE2;
307 >0 if it compares greater; 0 if it compares equal.
308 Report an error and exit if the comparison fails.
309 Use join fields JF_1 and JF_2 respectively. */
312 keycmp (struct line
const *line1
, struct line
const *line2
,
313 size_t jf_1
, size_t jf_2
)
315 /* Start of field to compare in each file. */
320 size_t len2
; /* Length of fields to compare. */
323 if (jf_1
< line1
->nfields
)
325 beg1
= line1
->fields
[jf_1
].beg
;
326 len1
= line1
->fields
[jf_1
].len
;
334 if (jf_2
< line2
->nfields
)
336 beg2
= line2
->fields
[jf_2
].beg
;
337 len2
= line2
->fields
[jf_2
].len
;
346 return len2
== 0 ? 0 : -1;
352 /* FIXME: ignore_case does not work with NLS (in particular,
353 with multibyte chars). */
354 diff
= memcasecmp (beg1
, beg2
, MIN (len1
, len2
));
359 return xmemcoll (beg1
, len1
, beg2
, len2
);
360 diff
= memcmp (beg1
, beg2
, MIN (len1
, len2
));
365 return len1
< len2
? -1 : len1
!= len2
;
368 /* Check that successive input lines PREV and CURRENT from input file
369 WHATFILE are presented in order, unless the user may be relying on
370 the GNU extension that input lines may be out of order if no input
371 lines are unpairable.
373 If the user specified --nocheck-order, the check is not made.
374 If the user specified --check-order, the problem is fatal.
375 Otherwise (the default), the message is simply a warning.
377 A message is printed at most once per input file. */
380 check_order (const struct line
*prev
,
381 const struct line
*current
,
384 if (check_input_order
!= CHECK_ORDER_DISABLED
385 && ((check_input_order
== CHECK_ORDER_ENABLED
) || seen_unpairable
))
387 if (!issued_disorder_warning
[whatfile
-1])
389 size_t join_field
= whatfile
== 1 ? join_field_1
: join_field_2
;
390 if (keycmp (prev
, current
, join_field
, join_field
) > 0)
392 /* Exclude any trailing newline. */
393 size_t len
= current
->buf
.length
;
394 if (0 < len
&& current
->buf
.buffer
[len
- 1] == '\n')
397 /* If the offending line is longer than INT_MAX, output
398 only the first INT_MAX bytes in this diagnostic. */
399 len
= MIN (INT_MAX
, len
);
401 error ((check_input_order
== CHECK_ORDER_ENABLED
403 0, _("%s:%ju: is not sorted: %.*s"),
404 g_names
[whatfile
- 1], line_no
[whatfile
- 1],
405 (int) len
, current
->buf
.buffer
);
407 /* If we get to here, the message was merely a warning.
408 Arrange to issue it only once per file. */
409 issued_disorder_warning
[whatfile
-1] = true;
416 reset_line (struct line
*line
)
422 init_linep (struct line
**linep
)
424 struct line
*line
= xcalloc (1, sizeof *line
);
429 /* Read a line from FP into LINE and split it into fields.
430 Return true if successful. */
433 get_line (FILE *fp
, struct line
**linep
, int which
)
435 struct line
*line
= *linep
;
437 if (line
== prevline
[which
- 1])
439 SWAPLINES (line
, spareline
[which
- 1]);
446 line
= init_linep (linep
);
448 if (! readlinebuffer (&line
->buf
, fp
))
451 error (EXIT_FAILURE
, errno
, _("read error"));
455 ++line_no
[which
- 1];
459 if (prevline
[which
- 1])
460 check_order (prevline
[which
- 1], line
, which
);
462 prevline
[which
- 1] = line
;
467 free_spareline (void)
471 for (i
= 0; i
< ARRAY_CARDINALITY (spareline
); i
++)
475 freeline (spareline
[i
]);
482 initseq (struct seq
*seq
)
489 /* Read a line from FP and add it to SEQ. Return true if successful. */
492 getseq (FILE *fp
, struct seq
*seq
, int whichfile
)
494 if (seq
->count
== seq
->alloc
)
497 seq
->lines
= X2NREALLOC (seq
->lines
, &seq
->alloc
);
498 for (i
= seq
->count
; i
< seq
->alloc
; i
++)
499 seq
->lines
[i
] = NULL
;
502 if (get_line (fp
, &seq
->lines
[seq
->count
], whichfile
))
510 /* Read a line from FP and add it to SEQ, as the first item if FIRST is
511 true, else as the next. */
513 advance_seq (FILE *fp
, struct seq
*seq
, bool first
, int whichfile
)
518 return getseq (fp
, seq
, whichfile
);
522 delseq (struct seq
*seq
)
525 for (i
= 0; i
< seq
->alloc
; i
++)
527 freeline (seq
->lines
[i
]);
528 free (seq
->lines
[i
]);
534 /* Print field N of LINE if it exists and is nonempty, otherwise
535 'empty_filler' if it is nonempty. */
538 prfield (size_t n
, struct line
const *line
)
542 if (n
< line
->nfields
)
544 len
= line
->fields
[n
].len
;
546 fwrite (line
->fields
[n
].beg
, 1, len
, stdout
);
547 else if (empty_filler
)
548 fputs (empty_filler
, stdout
);
550 else if (empty_filler
)
551 fputs (empty_filler
, stdout
);
554 /* Output all the fields in line, other than the join field. */
557 prfields (struct line
const *line
, size_t join_field
, size_t autocount
)
560 size_t nfields
= autoformat
? autocount
: line
->nfields
;
561 char output_separator
= tab
< 0 ? ' ' : tab
;
563 for (i
= 0; i
< join_field
&& i
< nfields
; ++i
)
565 putchar (output_separator
);
568 for (i
= join_field
+ 1; i
< nfields
; ++i
)
570 putchar (output_separator
);
575 /* Print the join of LINE1 and LINE2. */
578 prjoin (struct line
const *line1
, struct line
const *line2
)
580 const struct outlist
*outlist
;
581 char output_separator
= tab
< 0 ? ' ' : tab
;
583 struct line
const *line
;
585 outlist
= outlist_head
.next
;
588 const struct outlist
*o
;
595 if (line1
== &uni_blank
)
598 field
= join_field_2
;
603 field
= join_field_1
;
608 line
= (o
->file
== 1 ? line1
: line2
);
611 prfield (field
, line
);
615 putchar (output_separator
);
621 if (line1
== &uni_blank
)
624 field
= join_field_2
;
629 field
= join_field_1
;
632 /* Output the join field. */
633 prfield (field
, line
);
635 /* Output other fields. */
636 prfields (line1
, join_field_1
, autocount_1
);
637 prfields (line2
, join_field_2
, autocount_2
);
643 /* Print the join of the files in FP1 and FP2. */
646 join (FILE *fp1
, FILE *fp2
)
648 struct seq seq1
, seq2
;
652 fadvise (fp1
, FADVISE_SEQUENTIAL
);
653 fadvise (fp2
, FADVISE_SEQUENTIAL
);
655 /* Read the first line of each file. */
657 getseq (fp1
, &seq1
, 1);
659 getseq (fp2
, &seq2
, 2);
663 autocount_1
= seq1
.count
? seq1
.lines
[0]->nfields
: 0;
664 autocount_2
= seq2
.count
? seq2
.lines
[0]->nfields
: 0;
667 if (join_header_lines
&& (seq1
.count
|| seq2
.count
))
669 struct line
const *hline1
= seq1
.count
? seq1
.lines
[0] : &uni_blank
;
670 struct line
const *hline2
= seq2
.count
? seq2
.lines
[0] : &uni_blank
;
671 prjoin (hline1
, hline2
);
675 advance_seq (fp1
, &seq1
, true, 1);
677 advance_seq (fp2
, &seq2
, true, 2);
680 while (seq1
.count
&& seq2
.count
)
683 diff
= keycmp (seq1
.lines
[0], seq2
.lines
[0],
684 join_field_1
, join_field_2
);
687 if (print_unpairables_1
)
688 prjoin (seq1
.lines
[0], &uni_blank
);
689 advance_seq (fp1
, &seq1
, true, 1);
690 seen_unpairable
= true;
695 if (print_unpairables_2
)
696 prjoin (&uni_blank
, seq2
.lines
[0]);
697 advance_seq (fp2
, &seq2
, true, 2);
698 seen_unpairable
= true;
702 /* Keep reading lines from file1 as long as they continue to
703 match the current line from file2. */
706 if (!advance_seq (fp1
, &seq1
, false, 1))
712 while (!keycmp (seq1
.lines
[seq1
.count
- 1], seq2
.lines
[0],
713 join_field_1
, join_field_2
));
715 /* Keep reading lines from file2 as long as they continue to
716 match the current line from file1. */
719 if (!advance_seq (fp2
, &seq2
, false, 2))
725 while (!keycmp (seq1
.lines
[0], seq2
.lines
[seq2
.count
- 1],
726 join_field_1
, join_field_2
));
730 for (i
= 0; i
< seq1
.count
- 1; ++i
)
733 for (j
= 0; j
< seq2
.count
- 1; ++j
)
734 prjoin (seq1
.lines
[i
], seq2
.lines
[j
]);
740 SWAPLINES (seq1
.lines
[0], seq1
.lines
[seq1
.count
- 1]);
748 SWAPLINES (seq2
.lines
[0], seq2
.lines
[seq2
.count
- 1]);
755 /* If the user did not specify --nocheck-order, then we read the
756 tail ends of both inputs to verify that they are in order. We
757 skip the rest of the tail once we have issued a warning for that
758 file, unless we actually need to print the unpairable lines. */
759 struct line
*line
= NULL
;
760 bool checktail
= false;
762 if (check_input_order
!= CHECK_ORDER_DISABLED
763 && !(issued_disorder_warning
[0] && issued_disorder_warning
[1]))
766 if ((print_unpairables_1
|| checktail
) && seq1
.count
)
768 if (print_unpairables_1
)
769 prjoin (seq1
.lines
[0], &uni_blank
);
771 seen_unpairable
= true;
772 while (get_line (fp1
, &line
, 1))
774 if (print_unpairables_1
)
775 prjoin (line
, &uni_blank
);
776 if (issued_disorder_warning
[0] && !print_unpairables_1
)
781 if ((print_unpairables_2
|| checktail
) && seq2
.count
)
783 if (print_unpairables_2
)
784 prjoin (&uni_blank
, seq2
.lines
[0]);
786 seen_unpairable
= true;
787 while (get_line (fp2
, &line
, 2))
789 if (print_unpairables_2
)
790 prjoin (&uni_blank
, line
);
791 if (issued_disorder_warning
[1] && !print_unpairables_2
)
803 /* Add a field spec for field FIELD of file FILE to 'outlist'. */
806 add_field (int file
, size_t field
)
810 assert (file
== 0 || file
== 1 || file
== 2);
811 assert (file
!= 0 || field
== 0);
813 o
= xmalloc (sizeof *o
);
818 /* Add to the end of the list so the fields are in the right order. */
819 outlist_end
->next
= o
;
823 /* Convert a string of decimal digits, STR (the 1-based join field number),
824 to an integral value. Upon successful conversion, return one less
825 (the zero-based field number). Silently convert too-large values
826 to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a
827 diagnostic and exit. */
830 string_to_join_field (char const *str
)
833 unsigned long int val
;
834 verify (SIZE_MAX
<= ULONG_MAX
);
836 strtol_error s_err
= xstrtoul (str
, NULL
, 10, &val
, "");
837 if (s_err
== LONGINT_OVERFLOW
|| (s_err
== LONGINT_OK
&& SIZE_MAX
< val
))
839 else if (s_err
!= LONGINT_OK
|| val
== 0)
840 error (EXIT_FAILURE
, 0, _("invalid field number: %s"), quote (str
));
847 /* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
848 pair. In S, the field index string is 1-based; *FIELD_INDEX is zero-based.
849 If S is valid, return true. Otherwise, give a diagnostic and exit. */
852 decode_field_spec (const char *s
, int *file_index
, size_t *field_index
)
854 /* The first character must be 0, 1, or 2. */
860 /* '0' must be all alone -- no '.FIELD'. */
861 error (EXIT_FAILURE
, 0, _("invalid field specifier: %s"), quote (s
));
870 error (EXIT_FAILURE
, 0, _("invalid field specifier: %s"), quote (s
));
871 *file_index
= s
[0] - '0';
872 *field_index
= string_to_join_field (s
+ 2);
876 error (EXIT_FAILURE
, 0,
877 _("invalid file number in field spec: %s"), quote (s
));
879 /* Tell gcc -W -Wall that we can't get beyond this point.
880 This avoids a warning (otherwise legit) that the caller's copies
881 of *file_index and *field_index might be used uninitialized. */
888 /* Add the comma or blank separated field spec(s) in STR to 'outlist'. */
891 add_field_list (char *str
)
899 char const *spec_item
= p
;
901 p
= strpbrk (p
, ", \t");
904 decode_field_spec (spec_item
, &file_index
, &field_index
);
905 add_field (file_index
, field_index
);
910 /* Set the join field *VAR to VAL, but report an error if *VAR is set
911 more than once to incompatible values. */
914 set_join_field (size_t *var
, size_t val
)
916 if (*var
!= SIZE_MAX
&& *var
!= val
)
918 unsigned long int var1
= *var
+ 1;
919 unsigned long int val1
= val
+ 1;
920 error (EXIT_FAILURE
, 0, _("incompatible join fields %lu, %lu"),
926 /* Status of command-line arguments. */
930 /* This argument must be an operand, i.e., one of the files to be
934 /* This might be the argument of the preceding -j1 or -j2 option,
935 or it might be an operand. */
939 /* This might be the argument of the preceding -o option, or it might be
944 /* Add NAME to the array of input file NAMES with operand statuses
945 OPERAND_STATUS; currently there are NFILES names in the list. */
948 add_file_name (char *name
, char *names
[2],
949 int operand_status
[2], int joption_count
[2], int *nfiles
,
950 int *prev_optc_status
, int *optc_status
)
956 bool op0
= (operand_status
[0] == MUST_BE_OPERAND
);
957 char *arg
= names
[op0
];
958 switch (operand_status
[op0
])
960 case MUST_BE_OPERAND
:
961 error (0, 0, _("extra operand %s"), quote (name
));
962 usage (EXIT_FAILURE
);
964 case MIGHT_BE_J1_ARG
:
966 set_join_field (&join_field_1
, string_to_join_field (arg
));
969 case MIGHT_BE_J2_ARG
:
971 set_join_field (&join_field_2
, string_to_join_field (arg
));
975 add_field_list (arg
);
980 operand_status
[0] = operand_status
[1];
986 operand_status
[n
] = *prev_optc_status
;
989 if (*prev_optc_status
== MIGHT_BE_O_ARG
)
990 *optc_status
= MIGHT_BE_O_ARG
;
994 main (int argc
, char **argv
)
997 int prev_optc_status
= MUST_BE_OPERAND
;
998 int operand_status
[2];
999 int joption_count
[2] = { 0, 0 };
1005 initialize_main (&argc
, &argv
);
1006 set_program_name (argv
[0]);
1007 setlocale (LC_ALL
, "");
1008 bindtextdomain (PACKAGE
, LOCALEDIR
);
1009 textdomain (PACKAGE
);
1010 hard_LC_COLLATE
= hard_locale (LC_COLLATE
);
1012 atexit (close_stdout
);
1013 atexit (free_spareline
);
1015 print_pairables
= true;
1016 seen_unpairable
= false;
1017 issued_disorder_warning
[0] = issued_disorder_warning
[1] = false;
1018 check_input_order
= CHECK_ORDER_DEFAULT
;
1020 while ((optc
= getopt_long (argc
, argv
, "-a:e:i1:2:j:o:t:v:",
1024 optc_status
= MUST_BE_OPERAND
;
1029 print_pairables
= false;
1034 unsigned long int val
;
1035 if (xstrtoul (optarg
, NULL
, 10, &val
, "") != LONGINT_OK
1036 || (val
!= 1 && val
!= 2))
1037 error (EXIT_FAILURE
, 0,
1038 _("invalid field number: %s"), quote (optarg
));
1040 print_unpairables_1
= true;
1042 print_unpairables_2
= true;
1047 if (empty_filler
&& ! STREQ (empty_filler
, optarg
))
1048 error (EXIT_FAILURE
, 0,
1049 _("conflicting empty-field replacement strings"));
1050 empty_filler
= optarg
;
1058 set_join_field (&join_field_1
, string_to_join_field (optarg
));
1062 set_join_field (&join_field_2
, string_to_join_field (optarg
));
1066 if ((optarg
[0] == '1' || optarg
[0] == '2') && !optarg
[1]
1067 && optarg
== argv
[optind
- 1] + 2)
1069 /* The argument was either "-j1" or "-j2". */
1070 bool is_j2
= (optarg
[0] == '2');
1071 joption_count
[is_j2
]++;
1072 optc_status
= MIGHT_BE_J1_ARG
+ is_j2
;
1076 set_join_field (&join_field_1
, string_to_join_field (optarg
));
1077 set_join_field (&join_field_2
, join_field_1
);
1082 if (STREQ (optarg
, "auto"))
1086 add_field_list (optarg
);
1087 optc_status
= MIGHT_BE_O_ARG
;
1093 unsigned char newtab
= optarg
[0];
1095 newtab
= '\n'; /* '' => process the whole line. */
1098 if (STREQ (optarg
, "\\0"))
1101 error (EXIT_FAILURE
, 0, _("multi-character tab %s"),
1104 if (0 <= tab
&& tab
!= newtab
)
1105 error (EXIT_FAILURE
, 0, _("incompatible tabs"));
1110 case NOCHECK_ORDER_OPTION
:
1111 check_input_order
= CHECK_ORDER_DISABLED
;
1114 case CHECK_ORDER_OPTION
:
1115 check_input_order
= CHECK_ORDER_ENABLED
;
1118 case 1: /* Non-option argument. */
1119 add_file_name (optarg
, g_names
, operand_status
, joption_count
,
1120 &nfiles
, &prev_optc_status
, &optc_status
);
1123 case HEADER_LINE_OPTION
:
1124 join_header_lines
= true;
1127 case_GETOPT_HELP_CHAR
;
1129 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1132 usage (EXIT_FAILURE
);
1135 prev_optc_status
= optc_status
;
1138 /* Process any operands after "--". */
1139 prev_optc_status
= MUST_BE_OPERAND
;
1140 while (optind
< argc
)
1141 add_file_name (argv
[optind
++], g_names
, operand_status
, joption_count
,
1142 &nfiles
, &prev_optc_status
, &optc_status
);
1147 error (0, 0, _("missing operand"));
1149 error (0, 0, _("missing operand after %s"), quote (argv
[argc
- 1]));
1150 usage (EXIT_FAILURE
);
1153 /* If "-j1" was specified and it turns out not to have had an argument,
1154 treat it as "-j 1". Likewise for -j2. */
1155 for (i
= 0; i
< 2; i
++)
1156 if (joption_count
[i
] != 0)
1158 set_join_field (&join_field_1
, i
);
1159 set_join_field (&join_field_2
, i
);
1162 if (join_field_1
== SIZE_MAX
)
1164 if (join_field_2
== SIZE_MAX
)
1167 fp1
= STREQ (g_names
[0], "-") ? stdin
: fopen (g_names
[0], "r");
1169 error (EXIT_FAILURE
, errno
, "%s", g_names
[0]);
1170 fp2
= STREQ (g_names
[1], "-") ? stdin
: fopen (g_names
[1], "r");
1172 error (EXIT_FAILURE
, errno
, "%s", g_names
[1]);
1174 error (EXIT_FAILURE
, errno
, _("both files cannot be standard input"));
1177 if (fclose (fp1
) != 0)
1178 error (EXIT_FAILURE
, errno
, "%s", g_names
[0]);
1179 if (fclose (fp2
) != 0)
1180 error (EXIT_FAILURE
, errno
, "%s", g_names
[1]);
1182 if (issued_disorder_warning
[0] || issued_disorder_warning
[1])
1183 exit (EXIT_FAILURE
);
1185 exit (EXIT_SUCCESS
);