1 /* join - join lines of two files on a common field
2 Copyright (C) 1991-2022 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 <https://www.gnu.org/licenses/>.
17 Written by Mike Haertel, mike@gnu.ai.mit.edu. */
22 #include <sys/types.h>
29 #include "hard-locale.h"
30 #include "linebuffer.h"
31 #include "memcasecmp.h"
38 /* The official name of this program (e.g., no 'g' prefix). */
39 #define PROGRAM_NAME "join"
41 #define AUTHORS proper_name ("Mike Haertel")
43 #define join system_join
45 #define SWAPLINES(a, b) do { \
46 struct line *tmp = a; \
51 /* An element of the list identifying which fields to print for each
55 /* File number: 0, 1, or 2. 0 means use the join field.
56 1 means use the first file argument, 2 the second. */
59 /* Field index (zero-based), specified only when FILE is 1 or 2. */
65 /* A field of a line. */
68 char *beg
; /* First character in field. */
69 size_t len
; /* The length of the field. */
72 /* A line read from an input file. */
75 struct linebuffer buf
; /* The line itself. */
76 size_t nfields
; /* Number of elements in 'fields'. */
77 size_t nfields_allocated
; /* Number of elements allocated for 'fields'. */
81 /* One or more consecutive lines read from a file that all have the
82 same join field value. */
85 size_t count
; /* Elements used in 'lines'. */
86 size_t alloc
; /* Elements allocated in 'lines'. */
90 /* The previous line read from each file. */
91 static struct line
*prevline
[2] = {NULL
, NULL
};
93 /* The number of lines read from each file. */
94 static uintmax_t line_no
[2] = {0, 0};
96 /* The input file names. */
97 static char *g_names
[2];
99 /* This provides an extra line buffer for each file. We need these if we
100 try to read two consecutive lines into the same buffer, since we don't
101 want to overwrite the previous buffer before we check order. */
102 static struct line
*spareline
[2] = {NULL
, NULL
};
104 /* True if the LC_COLLATE locale is hard. */
105 static bool hard_LC_COLLATE
;
107 /* If nonzero, print unpairable lines in file 1 or 2. */
108 static bool print_unpairables_1
, print_unpairables_2
;
110 /* If nonzero, print pairable lines. */
111 static bool print_pairables
;
113 /* If nonzero, we have seen at least one unpairable line. */
114 static bool seen_unpairable
;
116 /* If nonzero, we have warned about disorder in that file. */
117 static bool issued_disorder_warning
[2];
119 /* Empty output field filler. */
120 static char const *empty_filler
;
122 /* Whether to ensure the same number of fields are output from each line. */
123 static bool autoformat
;
124 /* The number of fields to output for each line.
125 Only significant when autoformat is true. */
126 static size_t autocount_1
;
127 static size_t autocount_2
;
129 /* Field to join on; SIZE_MAX means they haven't been determined yet. */
130 static size_t join_field_1
= SIZE_MAX
;
131 static size_t join_field_2
= SIZE_MAX
;
133 /* List of fields to print. */
134 static struct outlist outlist_head
;
136 /* Last element in 'outlist', where a new element can be added. */
137 static struct outlist
*outlist_end
= &outlist_head
;
139 /* Tab character separating fields. If negative, fields are separated
140 by any nonempty string of blanks, otherwise by exactly one
141 tab character whose value (when cast to unsigned char) equals TAB. */
144 /* If nonzero, check that the input is correctly ordered. */
154 CHECK_ORDER_OPTION
= CHAR_MAX
+ 1,
155 NOCHECK_ORDER_OPTION
,
160 static struct option
const longopts
[] =
162 {"ignore-case", no_argument
, NULL
, 'i'},
163 {"check-order", no_argument
, NULL
, CHECK_ORDER_OPTION
},
164 {"nocheck-order", no_argument
, NULL
, NOCHECK_ORDER_OPTION
},
165 {"zero-terminated", no_argument
, NULL
, 'z'},
166 {"header", no_argument
, NULL
, HEADER_LINE_OPTION
},
167 {GETOPT_HELP_OPTION_DECL
},
168 {GETOPT_VERSION_OPTION_DECL
},
172 /* Used to print non-joining lines */
173 static struct line uni_blank
;
175 /* If nonzero, ignore case when comparing join fields. */
176 static bool ignore_case
;
178 /* If nonzero, treat the first line of each file as column headers --
179 join them without checking for ordering */
180 static bool join_header_lines
;
182 /* The character marking end of line. Default to \n. */
183 static char eolchar
= '\n';
188 if (status
!= EXIT_SUCCESS
)
193 Usage: %s [OPTION]... FILE1 FILE2\n\
197 For each pair of input lines with identical join fields, write a line to\n\
198 standard output. The default join field is the first, delimited by blanks.\
203 When FILE1 or FILE2 (not both) is -, read standard input.\n\
207 -a FILENUM also print unpairable lines from file FILENUM, where\n\
208 FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\
209 -e EMPTY replace missing input fields with EMPTY\n\
212 -i, --ignore-case ignore differences in case when comparing fields\n\
213 -j FIELD equivalent to '-1 FIELD -2 FIELD'\n\
214 -o FORMAT obey FORMAT while constructing output line\n\
215 -t CHAR use CHAR as input and output field separator\n\
218 -v FILENUM like -a FILENUM, but suppress joined output lines\n\
219 -1 FIELD join on this FIELD of file 1\n\
220 -2 FIELD join on this FIELD of file 2\n\
221 --check-order check that the input is correctly sorted, even\n\
222 if all input lines are pairable\n\
223 --nocheck-order do not check that the input is correctly sorted\n\
224 --header treat the first line in each file as field headers,\n\
225 print them without trying to pair them\n\
228 -z, --zero-terminated line delimiter is NUL, not newline\n\
230 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
231 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
234 Unless -t CHAR is given, leading blanks separate fields and are ignored,\n\
235 else fields are separated by CHAR. Any FIELD is a field number counted\n\
236 from 1. FORMAT is one or more comma or blank separated specifications,\n\
237 each being 'FILENUM.FIELD' or '0'. Default FORMAT outputs the join field,\n\
238 the remaining fields from FILE1, the remaining fields from FILE2, all\n\
239 separated by CHAR. If FORMAT is the keyword 'auto', then the first\n\
240 line of each file determines the number of fields output for each line.\n\
242 Important: FILE1 and FILE2 must be sorted on the join fields.\n\
243 E.g., use \"sort -k 1b,1\" if 'join' has no options,\n\
244 or use \"join -t ''\" if 'sort' has no options.\n\
245 Note, comparisons honor the rules specified by 'LC_COLLATE'.\n\
246 If the input is not sorted and some lines cannot be joined, a\n\
247 warning message will be given.\n\
249 emit_ancillary_info (PROGRAM_NAME
);
254 /* Record a field in LINE, with location FIELD and size LEN. */
257 extract_field (struct line
*line
, char *field
, size_t len
)
259 if (line
->nfields
>= line
->nfields_allocated
)
261 line
->fields
= X2NREALLOC (line
->fields
, &line
->nfields_allocated
);
263 line
->fields
[line
->nfields
].beg
= field
;
264 line
->fields
[line
->nfields
].len
= len
;
268 /* Fill in the 'fields' structure in LINE. */
271 xfields (struct line
*line
)
273 char *ptr
= line
->buf
.buffer
;
274 char const *lim
= ptr
+ line
->buf
.length
- 1;
279 if (0 <= tab
&& tab
!= '\n')
282 for (; (sep
= memchr (ptr
, tab
, lim
- ptr
)) != NULL
; ptr
= sep
+ 1)
283 extract_field (line
, ptr
, sep
- ptr
);
287 /* Skip leading blanks before the first field. */
288 while (field_sep (*ptr
))
295 for (sep
= ptr
+ 1; sep
!= lim
&& ! field_sep (*sep
); sep
++)
297 extract_field (line
, ptr
, sep
- ptr
);
300 for (ptr
= sep
+ 1; ptr
!= lim
&& field_sep (*ptr
); ptr
++)
306 extract_field (line
, ptr
, lim
- ptr
);
310 freeline (struct line
*line
)
316 free (line
->buf
.buffer
);
317 line
->buf
.buffer
= NULL
;
320 /* Return <0 if the join field in LINE1 compares less than the one in LINE2;
321 >0 if it compares greater; 0 if it compares equal.
322 Report an error and exit if the comparison fails.
323 Use join fields JF_1 and JF_2 respectively. */
326 keycmp (struct line
const *line1
, struct line
const *line2
,
327 size_t jf_1
, size_t jf_2
)
329 /* Start of field to compare in each file. */
334 size_t len2
; /* Length of fields to compare. */
337 if (jf_1
< line1
->nfields
)
339 beg1
= line1
->fields
[jf_1
].beg
;
340 len1
= line1
->fields
[jf_1
].len
;
348 if (jf_2
< line2
->nfields
)
350 beg2
= line2
->fields
[jf_2
].beg
;
351 len2
= line2
->fields
[jf_2
].len
;
360 return len2
== 0 ? 0 : -1;
366 /* FIXME: ignore_case does not work with NLS (in particular,
367 with multibyte chars). */
368 diff
= memcasecmp (beg1
, beg2
, MIN (len1
, len2
));
373 return xmemcoll (beg1
, len1
, beg2
, len2
);
374 diff
= memcmp (beg1
, beg2
, MIN (len1
, len2
));
379 return len1
< len2
? -1 : len1
!= len2
;
382 /* Check that successive input lines PREV and CURRENT from input file
383 WHATFILE are presented in order, unless the user may be relying on
384 the GNU extension that input lines may be out of order if no input
385 lines are unpairable.
387 If the user specified --nocheck-order, the check is not made.
388 If the user specified --check-order, the problem is fatal.
389 Otherwise (the default), the message is simply a warning.
391 A message is printed at most once per input file. */
394 check_order (const struct line
*prev
,
395 const struct line
*current
,
398 if (check_input_order
!= CHECK_ORDER_DISABLED
399 && ((check_input_order
== CHECK_ORDER_ENABLED
) || seen_unpairable
))
401 if (!issued_disorder_warning
[whatfile
- 1])
403 size_t join_field
= whatfile
== 1 ? join_field_1
: join_field_2
;
404 if (keycmp (prev
, current
, join_field
, join_field
) > 0)
406 /* Exclude any trailing newline. */
407 size_t len
= current
->buf
.length
;
408 if (0 < len
&& current
->buf
.buffer
[len
- 1] == '\n')
411 /* If the offending line is longer than INT_MAX, output
412 only the first INT_MAX bytes in this diagnostic. */
413 len
= MIN (INT_MAX
, len
);
415 error ((check_input_order
== CHECK_ORDER_ENABLED
417 0, _("%s:%"PRIuMAX
": is not sorted: %.*s"),
418 g_names
[whatfile
- 1], line_no
[whatfile
- 1],
419 (int) len
, current
->buf
.buffer
);
421 /* If we get to here, the message was merely a warning.
422 Arrange to issue it only once per file. */
423 issued_disorder_warning
[whatfile
- 1] = true;
430 reset_line (struct line
*line
)
436 init_linep (struct line
**linep
)
438 struct line
*line
= xcalloc (1, sizeof *line
);
443 /* Read a line from FP into LINE and split it into fields.
444 Return true if successful. */
447 get_line (FILE *fp
, struct line
**linep
, int which
)
449 struct line
*line
= *linep
;
451 if (line
== prevline
[which
- 1])
453 SWAPLINES (line
, spareline
[which
- 1]);
460 line
= init_linep (linep
);
462 if (! readlinebuffer_delim (&line
->buf
, fp
, eolchar
))
465 die (EXIT_FAILURE
, errno
, _("read error"));
469 ++line_no
[which
- 1];
473 if (prevline
[which
- 1])
474 check_order (prevline
[which
- 1], line
, which
);
476 prevline
[which
- 1] = line
;
481 free_spareline (void)
483 for (size_t i
= 0; i
< ARRAY_CARDINALITY (spareline
); i
++)
487 freeline (spareline
[i
]);
494 initseq (struct seq
*seq
)
501 /* Read a line from FP and add it to SEQ. Return true if successful. */
504 getseq (FILE *fp
, struct seq
*seq
, int whichfile
)
506 if (seq
->count
== seq
->alloc
)
508 seq
->lines
= X2NREALLOC (seq
->lines
, &seq
->alloc
);
509 for (size_t i
= seq
->count
; i
< seq
->alloc
; i
++)
510 seq
->lines
[i
] = NULL
;
513 if (get_line (fp
, &seq
->lines
[seq
->count
], whichfile
))
521 /* Read a line from FP and add it to SEQ, as the first item if FIRST is
522 true, else as the next. */
524 advance_seq (FILE *fp
, struct seq
*seq
, bool first
, int whichfile
)
529 return getseq (fp
, seq
, whichfile
);
533 delseq (struct seq
*seq
)
535 for (size_t i
= 0; i
< seq
->alloc
; i
++)
537 freeline (seq
->lines
[i
]);
538 free (seq
->lines
[i
]);
544 /* Print field N of LINE if it exists and is nonempty, otherwise
545 'empty_filler' if it is nonempty. */
548 prfield (size_t n
, struct line
const *line
)
552 if (n
< line
->nfields
)
554 len
= line
->fields
[n
].len
;
556 fwrite (line
->fields
[n
].beg
, 1, len
, stdout
);
557 else if (empty_filler
)
558 fputs (empty_filler
, stdout
);
560 else if (empty_filler
)
561 fputs (empty_filler
, stdout
);
564 /* Output all the fields in line, other than the join field. */
567 prfields (struct line
const *line
, size_t join_field
, size_t autocount
)
570 size_t nfields
= autoformat
? autocount
: line
->nfields
;
571 char output_separator
= tab
< 0 ? ' ' : tab
;
573 for (i
= 0; i
< join_field
&& i
< nfields
; ++i
)
575 putchar (output_separator
);
578 for (i
= join_field
+ 1; i
< nfields
; ++i
)
580 putchar (output_separator
);
585 /* Print the join of LINE1 and LINE2. */
588 prjoin (struct line
const *line1
, struct line
const *line2
)
590 const struct outlist
*outlist
;
591 char output_separator
= tab
< 0 ? ' ' : tab
;
593 struct line
const *line
;
595 outlist
= outlist_head
.next
;
598 const struct outlist
*o
;
605 if (line1
== &uni_blank
)
608 field
= join_field_2
;
613 field
= join_field_1
;
618 line
= (o
->file
== 1 ? line1
: line2
);
621 prfield (field
, line
);
625 putchar (output_separator
);
631 if (line1
== &uni_blank
)
634 field
= join_field_2
;
639 field
= join_field_1
;
642 /* Output the join field. */
643 prfield (field
, line
);
645 /* Output other fields. */
646 prfields (line1
, join_field_1
, autocount_1
);
647 prfields (line2
, join_field_2
, autocount_2
);
653 /* Print the join of the files in FP1 and FP2. */
656 join (FILE *fp1
, FILE *fp2
)
658 struct seq seq1
, seq2
;
662 fadvise (fp1
, FADVISE_SEQUENTIAL
);
663 fadvise (fp2
, FADVISE_SEQUENTIAL
);
665 /* Read the first line of each file. */
667 getseq (fp1
, &seq1
, 1);
669 getseq (fp2
, &seq2
, 2);
673 autocount_1
= seq1
.count
? seq1
.lines
[0]->nfields
: 0;
674 autocount_2
= seq2
.count
? seq2
.lines
[0]->nfields
: 0;
677 if (join_header_lines
&& (seq1
.count
|| seq2
.count
))
679 struct line
const *hline1
= seq1
.count
? seq1
.lines
[0] : &uni_blank
;
680 struct line
const *hline2
= seq2
.count
? seq2
.lines
[0] : &uni_blank
;
681 prjoin (hline1
, hline2
);
685 advance_seq (fp1
, &seq1
, true, 1);
687 advance_seq (fp2
, &seq2
, true, 2);
690 while (seq1
.count
&& seq2
.count
)
692 diff
= keycmp (seq1
.lines
[0], seq2
.lines
[0],
693 join_field_1
, join_field_2
);
696 if (print_unpairables_1
)
697 prjoin (seq1
.lines
[0], &uni_blank
);
698 advance_seq (fp1
, &seq1
, true, 1);
699 seen_unpairable
= true;
704 if (print_unpairables_2
)
705 prjoin (&uni_blank
, seq2
.lines
[0]);
706 advance_seq (fp2
, &seq2
, true, 2);
707 seen_unpairable
= true;
711 /* Keep reading lines from file1 as long as they continue to
712 match the current line from file2. */
715 if (!advance_seq (fp1
, &seq1
, false, 1))
721 while (!keycmp (seq1
.lines
[seq1
.count
- 1], seq2
.lines
[0],
722 join_field_1
, join_field_2
));
724 /* Keep reading lines from file2 as long as they continue to
725 match the current line from file1. */
728 if (!advance_seq (fp2
, &seq2
, false, 2))
734 while (!keycmp (seq1
.lines
[0], seq2
.lines
[seq2
.count
- 1],
735 join_field_1
, join_field_2
));
739 for (size_t i
= 0; i
< seq1
.count
- 1; ++i
)
742 for (j
= 0; j
< seq2
.count
- 1; ++j
)
743 prjoin (seq1
.lines
[i
], seq2
.lines
[j
]);
749 SWAPLINES (seq1
.lines
[0], seq1
.lines
[seq1
.count
- 1]);
757 SWAPLINES (seq2
.lines
[0], seq2
.lines
[seq2
.count
- 1]);
764 /* If the user did not specify --nocheck-order, then we read the
765 tail ends of both inputs to verify that they are in order. We
766 skip the rest of the tail once we have issued a warning for that
767 file, unless we actually need to print the unpairable lines. */
768 struct line
*line
= NULL
;
769 bool checktail
= false;
771 if (check_input_order
!= CHECK_ORDER_DISABLED
772 && !(issued_disorder_warning
[0] && issued_disorder_warning
[1]))
775 if ((print_unpairables_1
|| checktail
) && seq1
.count
)
777 if (print_unpairables_1
)
778 prjoin (seq1
.lines
[0], &uni_blank
);
780 seen_unpairable
= true;
781 while (get_line (fp1
, &line
, 1))
783 if (print_unpairables_1
)
784 prjoin (line
, &uni_blank
);
785 if (issued_disorder_warning
[0] && !print_unpairables_1
)
790 if ((print_unpairables_2
|| checktail
) && seq2
.count
)
792 if (print_unpairables_2
)
793 prjoin (&uni_blank
, seq2
.lines
[0]);
795 seen_unpairable
= true;
796 while (get_line (fp2
, &line
, 2))
798 if (print_unpairables_2
)
799 prjoin (&uni_blank
, line
);
800 if (issued_disorder_warning
[1] && !print_unpairables_2
)
812 /* Add a field spec for field FIELD of file FILE to 'outlist'. */
815 add_field (int file
, size_t field
)
819 assert (file
== 0 || file
== 1 || file
== 2);
820 assert (file
!= 0 || field
== 0);
822 o
= xmalloc (sizeof *o
);
827 /* Add to the end of the list so the fields are in the right order. */
828 outlist_end
->next
= o
;
832 /* Convert a string of decimal digits, STR (the 1-based join field number),
833 to an integral value. Upon successful conversion, return one less
834 (the zero-based field number). Silently convert too-large values
835 to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a
836 diagnostic and exit. */
839 string_to_join_field (char const *str
)
844 strtol_error s_err
= xstrtoumax (str
, NULL
, 10, &val
, "");
845 if (s_err
== LONGINT_OVERFLOW
|| (s_err
== LONGINT_OK
&& SIZE_MAX
< val
))
847 else if (s_err
!= LONGINT_OK
|| val
== 0)
848 die (EXIT_FAILURE
, 0, _("invalid field number: %s"), quote (str
));
855 /* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
856 pair. In S, the field index string is 1-based; *FIELD_INDEX is zero-based.
857 If S is valid, return true. Otherwise, give a diagnostic and exit. */
860 decode_field_spec (char const *s
, int *file_index
, size_t *field_index
)
862 /* The first character must be 0, 1, or 2. */
868 /* '0' must be all alone -- no '.FIELD'. */
869 die (EXIT_FAILURE
, 0, _("invalid field specifier: %s"), quote (s
));
878 die (EXIT_FAILURE
, 0, _("invalid field specifier: %s"), quote (s
));
879 *file_index
= s
[0] - '0';
880 *field_index
= string_to_join_field (s
+ 2);
884 die (EXIT_FAILURE
, 0,
885 _("invalid file number in field spec: %s"), quote (s
));
887 /* Tell gcc -W -Wall that we can't get beyond this point.
888 This avoids a warning (otherwise legit) that the caller's copies
889 of *file_index and *field_index might be used uninitialized. */
896 /* Add the comma or blank separated field spec(s) in STR to 'outlist'. */
899 add_field_list (char *str
)
907 char const *spec_item
= p
;
909 p
= strpbrk (p
, ", \t");
912 decode_field_spec (spec_item
, &file_index
, &field_index
);
913 add_field (file_index
, field_index
);
918 /* Set the join field *VAR to VAL, but report an error if *VAR is set
919 more than once to incompatible values. */
922 set_join_field (size_t *var
, size_t val
)
924 if (*var
!= SIZE_MAX
&& *var
!= val
)
926 unsigned long int var1
= *var
+ 1;
927 unsigned long int val1
= val
+ 1;
928 die (EXIT_FAILURE
, 0,
929 _("incompatible join fields %lu, %lu"), var1
, val1
);
934 /* Status of command-line arguments. */
938 /* This argument must be an operand, i.e., one of the files to be
942 /* This might be the argument of the preceding -j1 or -j2 option,
943 or it might be an operand. */
947 /* This might be the argument of the preceding -o option, or it might be
952 /* Add NAME to the array of input file NAMES with operand statuses
953 OPERAND_STATUS; currently there are NFILES names in the list. */
956 add_file_name (char *name
, char *names
[2],
957 int operand_status
[2], int joption_count
[2], int *nfiles
,
958 int *prev_optc_status
, int *optc_status
)
964 bool op0
= (operand_status
[0] == MUST_BE_OPERAND
);
965 char *arg
= names
[op0
];
966 switch (operand_status
[op0
])
968 case MUST_BE_OPERAND
:
969 error (0, 0, _("extra operand %s"), quoteaf (name
));
970 usage (EXIT_FAILURE
);
972 case MIGHT_BE_J1_ARG
:
974 set_join_field (&join_field_1
, string_to_join_field (arg
));
977 case MIGHT_BE_J2_ARG
:
979 set_join_field (&join_field_2
, string_to_join_field (arg
));
983 add_field_list (arg
);
988 operand_status
[0] = operand_status
[1];
994 operand_status
[n
] = *prev_optc_status
;
997 if (*prev_optc_status
== MIGHT_BE_O_ARG
)
998 *optc_status
= MIGHT_BE_O_ARG
;
1002 main (int argc
, char **argv
)
1005 int prev_optc_status
= MUST_BE_OPERAND
;
1006 int operand_status
[2];
1007 int joption_count
[2] = { 0, 0 };
1013 initialize_main (&argc
, &argv
);
1014 set_program_name (argv
[0]);
1015 setlocale (LC_ALL
, "");
1016 bindtextdomain (PACKAGE
, LOCALEDIR
);
1017 textdomain (PACKAGE
);
1018 hard_LC_COLLATE
= hard_locale (LC_COLLATE
);
1020 atexit (close_stdout
);
1021 atexit (free_spareline
);
1023 print_pairables
= true;
1024 seen_unpairable
= false;
1025 issued_disorder_warning
[0] = issued_disorder_warning
[1] = false;
1026 check_input_order
= CHECK_ORDER_DEFAULT
;
1028 while ((optc
= getopt_long (argc
, argv
, "-a:e:i1:2:j:o:t:v:z",
1032 optc_status
= MUST_BE_OPERAND
;
1037 print_pairables
= false;
1042 unsigned long int val
;
1043 if (xstrtoul (optarg
, NULL
, 10, &val
, "") != LONGINT_OK
1044 || (val
!= 1 && val
!= 2))
1045 die (EXIT_FAILURE
, 0,
1046 _("invalid field number: %s"), quote (optarg
));
1048 print_unpairables_1
= true;
1050 print_unpairables_2
= true;
1055 if (empty_filler
&& ! STREQ (empty_filler
, optarg
))
1056 die (EXIT_FAILURE
, 0,
1057 _("conflicting empty-field replacement strings"));
1058 empty_filler
= optarg
;
1066 set_join_field (&join_field_1
, string_to_join_field (optarg
));
1070 set_join_field (&join_field_2
, string_to_join_field (optarg
));
1074 if ((optarg
[0] == '1' || optarg
[0] == '2') && !optarg
[1]
1075 && optarg
== argv
[optind
- 1] + 2)
1077 /* The argument was either "-j1" or "-j2". */
1078 bool is_j2
= (optarg
[0] == '2');
1079 joption_count
[is_j2
]++;
1080 optc_status
= MIGHT_BE_J1_ARG
+ is_j2
;
1084 set_join_field (&join_field_1
, string_to_join_field (optarg
));
1085 set_join_field (&join_field_2
, join_field_1
);
1090 if (STREQ (optarg
, "auto"))
1094 add_field_list (optarg
);
1095 optc_status
= MIGHT_BE_O_ARG
;
1101 unsigned char newtab
= optarg
[0];
1103 newtab
= '\n'; /* '' => process the whole line. */
1106 if (STREQ (optarg
, "\\0"))
1109 die (EXIT_FAILURE
, 0, _("multi-character tab %s"),
1112 if (0 <= tab
&& tab
!= newtab
)
1113 die (EXIT_FAILURE
, 0, _("incompatible tabs"));
1122 case NOCHECK_ORDER_OPTION
:
1123 check_input_order
= CHECK_ORDER_DISABLED
;
1126 case CHECK_ORDER_OPTION
:
1127 check_input_order
= CHECK_ORDER_ENABLED
;
1130 case 1: /* Non-option argument. */
1131 add_file_name (optarg
, g_names
, operand_status
, joption_count
,
1132 &nfiles
, &prev_optc_status
, &optc_status
);
1135 case HEADER_LINE_OPTION
:
1136 join_header_lines
= true;
1139 case_GETOPT_HELP_CHAR
;
1141 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1144 usage (EXIT_FAILURE
);
1147 prev_optc_status
= optc_status
;
1150 /* Process any operands after "--". */
1151 prev_optc_status
= MUST_BE_OPERAND
;
1152 while (optind
< argc
)
1153 add_file_name (argv
[optind
++], g_names
, operand_status
, joption_count
,
1154 &nfiles
, &prev_optc_status
, &optc_status
);
1159 error (0, 0, _("missing operand"));
1161 error (0, 0, _("missing operand after %s"), quote (argv
[argc
- 1]));
1162 usage (EXIT_FAILURE
);
1165 /* If "-j1" was specified and it turns out not to have had an argument,
1166 treat it as "-j 1". Likewise for -j2. */
1167 for (i
= 0; i
< 2; i
++)
1168 if (joption_count
[i
] != 0)
1170 set_join_field (&join_field_1
, i
);
1171 set_join_field (&join_field_2
, i
);
1174 if (join_field_1
== SIZE_MAX
)
1176 if (join_field_2
== SIZE_MAX
)
1179 fp1
= STREQ (g_names
[0], "-") ? stdin
: fopen (g_names
[0], "r");
1181 die (EXIT_FAILURE
, errno
, "%s", quotef (g_names
[0]));
1182 fp2
= STREQ (g_names
[1], "-") ? stdin
: fopen (g_names
[1], "r");
1184 die (EXIT_FAILURE
, errno
, "%s", quotef (g_names
[1]));
1186 die (EXIT_FAILURE
, errno
, _("both files cannot be standard input"));
1189 if (fclose (fp1
) != 0)
1190 die (EXIT_FAILURE
, errno
, "%s", quotef (g_names
[0]));
1191 if (fclose (fp2
) != 0)
1192 die (EXIT_FAILURE
, errno
, "%s", quotef (g_names
[1]));
1194 if (issued_disorder_warning
[0] || issued_disorder_warning
[1])
1195 die (EXIT_FAILURE
, 0, _("input is not in sorted order"));
1197 return EXIT_SUCCESS
;