30fbd439c4d8ad19202312d3b7c6b225c04ca552
[platform/upstream/coreutils.git] / src / join.c
1 /* join - join lines of two files on a common field
2    Copyright (C) 91, 1995-2006, 2008 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17    Written by Mike Haertel, mike@gnu.ai.mit.edu.  */
18
19 #include <config.h>
20
21 #include <assert.h>
22 #include <sys/types.h>
23 #include <getopt.h>
24
25 #include "system.h"
26 #include "error.h"
27 #include "hard-locale.h"
28 #include "linebuffer.h"
29 #include "memcasecmp.h"
30 #include "quote.h"
31 #include "stdio--.h"
32 #include "xmemcoll.h"
33 #include "xstrtol.h"
34 #include "argmatch.h"
35
36 /* The official name of this program (e.g., no `g' prefix).  */
37 #define PROGRAM_NAME "join"
38
39 #define AUTHORS "Mike Haertel"
40
41 #define join system_join
42
43 /* An element of the list identifying which fields to print for each
44    output line.  */
45 struct outlist
46   {
47     /* File number: 0, 1, or 2.  0 means use the join field.
48        1 means use the first file argument, 2 the second.  */
49     int file;
50
51     /* Field index (zero-based), specified only when FILE is 1 or 2.  */
52     size_t field;
53
54     struct outlist *next;
55   };
56
57 /* A field of a line.  */
58 struct field
59   {
60     char *beg;                  /* First character in field.  */
61     size_t len;                 /* The length of the field.  */
62   };
63
64 /* A line read from an input file.  */
65 struct line
66   {
67     struct linebuffer buf;      /* The line itself.  */
68     size_t nfields;             /* Number of elements in `fields'.  */
69     size_t nfields_allocated;   /* Number of elements allocated for `fields'. */
70     struct field *fields;
71   };
72
73 /* One or more consecutive lines read from a file that all have the
74    same join field value.  */
75 struct seq
76   {
77     size_t count;                       /* Elements used in `lines'.  */
78     size_t alloc;                       /* Elements allocated in `lines'.  */
79     struct line *lines;
80   };
81
82 /* The name this program was run with.  */
83 char *program_name;
84
85 /* The previous line read from each file. */
86 static struct line *prevline[2];
87
88 /* True if the LC_COLLATE locale is hard.  */
89 static bool hard_LC_COLLATE;
90
91 /* If nonzero, print unpairable lines in file 1 or 2.  */
92 static bool print_unpairables_1, print_unpairables_2;
93
94 /* If nonzero, print pairable lines.  */
95 static bool print_pairables;
96
97 /* If nonzero, we have seen at least one unpairable line. */
98 static bool seen_unpairable;
99
100 /* If nonzero, we have warned about disorder in that file. */
101 static bool issued_disorder_warning[2];
102
103 /* Empty output field filler.  */
104 static char const *empty_filler;
105
106 /* Field to join on; SIZE_MAX means they haven't been determined yet.  */
107 static size_t join_field_1 = SIZE_MAX;
108 static size_t join_field_2 = SIZE_MAX;
109
110 /* List of fields to print.  */
111 static struct outlist outlist_head;
112
113 /* Last element in `outlist', where a new element can be added.  */
114 static struct outlist *outlist_end = &outlist_head;
115
116 /* Tab character separating fields.  If negative, fields are separated
117    by any nonempty string of blanks, otherwise by exactly one
118    tab character whose value (when cast to unsigned char) equals TAB.  */
119 static int tab = -1;
120
121 /* If nonzero, check that the input is correctly ordered. */
122 static enum
123   {
124     CHECK_ORDER_DEFAULT,
125     CHECK_ORDER_ENABLED,
126     CHECK_ORDER_DISABLED
127   } check_input_order;
128
129 enum
130 {
131   CHECK_ORDER_OPTION = CHAR_MAX + 1,
132   NOCHECK_ORDER_OPTION
133 };
134
135
136 static struct option const longopts[] =
137 {
138   {"ignore-case", no_argument, NULL, 'i'},
139   {"check-order", no_argument, NULL, CHECK_ORDER_OPTION},
140   {"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION},
141   {GETOPT_HELP_OPTION_DECL},
142   {GETOPT_VERSION_OPTION_DECL},
143   {NULL, 0, NULL, 0}
144 };
145
146 /* Used to print non-joining lines */
147 static struct line uni_blank;
148
149 /* If nonzero, ignore case when comparing join fields.  */
150 static bool ignore_case;
151
152
153 static void checkorder (const struct line *, const struct line *, int);
154
155 void
156 usage (int status)
157 {
158   if (status != EXIT_SUCCESS)
159     fprintf (stderr, _("Try `%s --help' for more information.\n"),
160              program_name);
161   else
162     {
163       printf (_("\
164 Usage: %s [OPTION]... FILE1 FILE2\n\
165 "),
166               program_name);
167       fputs (_("\
168 For each pair of input lines with identical join fields, write a line to\n\
169 standard output.  The default join field is the first, delimited\n\
170 by whitespace.  When FILE1 or FILE2 (not both) is -, read standard input.\n\
171 \n\
172   -a FILENUM        print unpairable lines coming from file FILENUM, where\n\
173                       FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\
174   -e EMPTY          replace missing input fields with EMPTY\n\
175 "), stdout);
176       fputs (_("\
177   -i, --ignore-case  ignore differences in case when comparing fields\n\
178   -j FIELD          equivalent to `-1 FIELD -2 FIELD'\n\
179   -o FORMAT         obey FORMAT while constructing output line\n\
180   -t CHAR           use CHAR as input and output field separator\n\
181 "), stdout);
182       fputs (_("\
183   -v FILENUM        like -a FILENUM, but suppress joined output lines\n\
184   -1 FIELD          join on this FIELD of file 1\n\
185   -2 FIELD          join on this FIELD of file 2\n\
186   --check-order     check that the input is correctly sorted, even\n\
187                       if all input lines are pairable\n\
188   --nocheck-order   do not check that the input is correctly sorted\n\
189 "), stdout);
190       fputs (HELP_OPTION_DESCRIPTION, stdout);
191       fputs (VERSION_OPTION_DESCRIPTION, stdout);
192       fputs (_("\
193 \n\
194 Unless -t CHAR is given, leading blanks separate fields and are ignored,\n\
195 else fields are separated by CHAR.  Any FIELD is a field number counted\n\
196 from 1.  FORMAT is one or more comma or blank separated specifications,\n\
197 each being `FILENUM.FIELD' or `0'.  Default FORMAT outputs the join field,\n\
198 the remaining fields from FILE1, the remaining fields from FILE2, all\n\
199 separated by CHAR.\n\
200 \n\
201 Important: FILE1 and FILE2 must be sorted on the join fields.\n\
202 E.g., use `sort -k 1b,1' if `join' has no options.\n\
203 If the input is not sorted and some lines cannot be joined, a\n\
204 warning message will be given.\n\
205 "), stdout);
206       emit_bug_reporting_address ();
207     }
208   exit (status);
209 }
210
211 /* Record a field in LINE, with location FIELD and size LEN.  */
212
213 static void
214 extract_field (struct line *line, char *field, size_t len)
215 {
216   if (line->nfields >= line->nfields_allocated)
217     {
218       line->fields = X2NREALLOC (line->fields, &line->nfields_allocated);
219     }
220   line->fields[line->nfields].beg = field;
221   line->fields[line->nfields].len = len;
222   ++(line->nfields);
223 }
224
225 /* Fill in the `fields' structure in LINE.  */
226
227 static void
228 xfields (struct line *line)
229 {
230   char *ptr = line->buf.buffer;
231   char const *lim = ptr + line->buf.length - 1;
232
233   if (ptr == lim)
234     return;
235
236   if (0 <= tab)
237     {
238       char *sep;
239       for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
240         extract_field (line, ptr, sep - ptr);
241     }
242   else
243     {
244       /* Skip leading blanks before the first field.  */
245       while (isblank (to_uchar (*ptr)))
246         if (++ptr == lim)
247           return;
248
249       do
250         {
251           char *sep;
252           for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++)
253             continue;
254           extract_field (line, ptr, sep - ptr);
255           if (sep == lim)
256             return;
257           for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++)
258             continue;
259         }
260       while (ptr != lim);
261     }
262
263   extract_field (line, ptr, lim - ptr);
264 }
265
266 static struct line *
267 dup_line (const struct line *old)
268 {
269   struct line *newline = xmalloc (sizeof *newline);
270   size_t i;
271
272   /* Duplicate the buffer. */
273   initbuffer (&newline->buf);
274   newline->buf.buffer = xmalloc (old->buf.size);
275   newline->buf.size = old->buf.size;
276   memcpy (newline->buf.buffer, old->buf.buffer, old->buf.length);
277   newline->buf.length = old->buf.length;
278
279   /* Duplicate the field positions. */
280   newline->fields = xnmalloc (old->nfields_allocated, sizeof *newline->fields);
281   newline->nfields = old->nfields;
282   newline->nfields_allocated = old->nfields_allocated;
283
284   for (i = 0; i < old->nfields; i++)
285     {
286       newline->fields[i].len = old->fields[i].len;
287       newline->fields[i].beg = newline->buf.buffer + (old->fields[i].beg
288                                                       - old->buf.buffer);
289     }
290   return newline;
291 }
292
293 static void
294 freeline (struct line *line)
295 {
296   free (line->fields);
297   free (line->buf.buffer);
298   line->buf.buffer = NULL;
299 }
300
301 /* Read a line from FP into LINE and split it into fields.
302    Return true if successful.  */
303
304 static bool
305 get_line (FILE *fp, struct line *line, int which)
306 {
307   initbuffer (&line->buf);
308
309   if (! readlinebuffer (&line->buf, fp))
310     {
311       if (ferror (fp))
312         error (EXIT_FAILURE, errno, _("read error"));
313       free (line->buf.buffer);
314       line->buf.buffer = NULL;
315       return false;
316     }
317
318   line->nfields_allocated = 0;
319   line->nfields = 0;
320   line->fields = NULL;
321   xfields (line);
322
323   if (prevline[which - 1])
324     {
325       checkorder (prevline[which - 1], line, which);
326       freeline (prevline[which - 1]);
327       free (prevline[which - 1]);
328     }
329   prevline[which - 1] = dup_line (line);
330   return true;
331 }
332
333 static void
334 free_prevline (void)
335 {
336   size_t i;
337
338   for (i = 0; i < ARRAY_CARDINALITY (prevline); i++)
339     {
340       if (prevline[i])
341         freeline (prevline[i]);
342       free (prevline[i]);
343       prevline[i] = NULL;
344     }
345 }
346
347 static void
348 initseq (struct seq *seq)
349 {
350   seq->count = 0;
351   seq->alloc = 0;
352   seq->lines = NULL;
353 }
354
355 /* Read a line from FP and add it to SEQ.  Return true if successful.  */
356
357 static bool
358 getseq (FILE *fp, struct seq *seq, int whichfile)
359 {
360   if (seq->count == seq->alloc)
361     seq->lines = X2NREALLOC (seq->lines, &seq->alloc);
362
363   if (get_line (fp, &seq->lines[seq->count], whichfile))
364     {
365       ++seq->count;
366       return true;
367     }
368   return false;
369 }
370
371 /* Read a line from FP and add it to SEQ, as the first item if FIRST is
372    true, else as the next.  */
373 static bool
374 advance_seq (FILE *fp, struct seq *seq, bool first, int whichfile)
375 {
376   if (first)
377     {
378       freeline (&seq->lines[0]);
379       seq->count = 0;
380     }
381   return getseq (fp, seq, whichfile);
382 }
383
384 static void
385 delseq (struct seq *seq)
386 {
387   size_t i;
388   for (i = 0; i < seq->count; i++)
389     if (seq->lines[i].buf.buffer)
390       freeline (&seq->lines[i]);
391   free (seq->lines);
392 }
393
394 /* Return <0 if the join field in LINE1 compares less than the one in LINE2;
395    >0 if it compares greater; 0 if it compares equal.
396    Report an error and exit if the comparison fails.  */
397
398 static int
399 keycmp (struct line const *line1, struct line const *line2)
400 {
401   /* Start of field to compare in each file.  */
402   char *beg1;
403   char *beg2;
404
405   size_t len1;
406   size_t len2;          /* Length of fields to compare.  */
407   int diff;
408
409   if (join_field_1 < line1->nfields)
410     {
411       beg1 = line1->fields[join_field_1].beg;
412       len1 = line1->fields[join_field_1].len;
413     }
414   else
415     {
416       beg1 = NULL;
417       len1 = 0;
418     }
419
420   if (join_field_2 < line2->nfields)
421     {
422       beg2 = line2->fields[join_field_2].beg;
423       len2 = line2->fields[join_field_2].len;
424     }
425   else
426     {
427       beg2 = NULL;
428       len2 = 0;
429     }
430
431   if (len1 == 0)
432     return len2 == 0 ? 0 : -1;
433   if (len2 == 0)
434     return 1;
435
436   if (ignore_case)
437     {
438       /* FIXME: ignore_case does not work with NLS (in particular,
439          with multibyte chars).  */
440       diff = memcasecmp (beg1, beg2, MIN (len1, len2));
441     }
442   else
443     {
444       if (hard_LC_COLLATE)
445         return xmemcoll (beg1, len1, beg2, len2);
446       diff = memcmp (beg1, beg2, MIN (len1, len2));
447     }
448
449   if (diff)
450     return diff;
451   return len1 < len2 ? -1 : len1 != len2;
452 }
453
454
455
456 /* Check that successive input lines PREV and CURRENT from input file
457    WHATFILE are presented in order, unless the user may be relying on
458    the GNU extension that input lines may be out of order if no input
459    lines are unpairable.
460
461    If the user specified --nocheck-order, the check is not made.
462    If the user specified --check-order, the problem is fatal.
463    Otherwise (the default), the message is simply a warning.
464
465    A message is printed at most once per input file. */
466
467 static void
468 checkorder (const struct line *prev,
469             const struct line *current,
470             int whatfile)
471 {
472   if (check_input_order != CHECK_ORDER_DISABLED
473       && ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable))
474     {
475       if (!issued_disorder_warning[whatfile-1])
476         {
477           if (keycmp (prev, current) > 0)
478             {
479               error ((check_input_order == CHECK_ORDER_ENABLED ? 1 : 0),
480                      0, _("File %d is not in sorted order"), whatfile);
481
482               /* If we get to here, the message was just a warning, but we
483                  want only to issue it once. */
484               issued_disorder_warning[whatfile-1] = true;
485             }
486         }
487     }
488 }
489
490
491
492 /* Print field N of LINE if it exists and is nonempty, otherwise
493    `empty_filler' if it is nonempty.  */
494
495 static void
496 prfield (size_t n, struct line const *line)
497 {
498   size_t len;
499
500   if (n < line->nfields)
501     {
502       len = line->fields[n].len;
503       if (len)
504         fwrite (line->fields[n].beg, 1, len, stdout);
505       else if (empty_filler)
506         fputs (empty_filler, stdout);
507     }
508   else if (empty_filler)
509     fputs (empty_filler, stdout);
510 }
511
512 /* Print the join of LINE1 and LINE2.  */
513
514 static void
515 prjoin (struct line const *line1, struct line const *line2)
516 {
517   const struct outlist *outlist;
518   char output_separator = tab < 0 ? ' ' : tab;
519
520   outlist = outlist_head.next;
521   if (outlist)
522     {
523       const struct outlist *o;
524
525       o = outlist;
526       while (1)
527         {
528           size_t field;
529           struct line const *line;
530
531           if (o->file == 0)
532             {
533               if (line1 == &uni_blank)
534                 {
535                   line = line2;
536                   field = join_field_2;
537                 }
538               else
539                 {
540                   line = line1;
541                   field = join_field_1;
542                 }
543             }
544           else
545             {
546               line = (o->file == 1 ? line1 : line2);
547               field = o->field;
548             }
549           prfield (field, line);
550           o = o->next;
551           if (o == NULL)
552             break;
553           putchar (output_separator);
554         }
555       putchar ('\n');
556     }
557   else
558     {
559       size_t i;
560
561       if (line1 == &uni_blank)
562         {
563           struct line const *t;
564           t = line1;
565           line1 = line2;
566           line2 = t;
567         }
568       prfield (join_field_1, line1);
569       for (i = 0; i < join_field_1 && i < line1->nfields; ++i)
570         {
571           putchar (output_separator);
572           prfield (i, line1);
573         }
574       for (i = join_field_1 + 1; i < line1->nfields; ++i)
575         {
576           putchar (output_separator);
577           prfield (i, line1);
578         }
579
580       for (i = 0; i < join_field_2 && i < line2->nfields; ++i)
581         {
582           putchar (output_separator);
583           prfield (i, line2);
584         }
585       for (i = join_field_2 + 1; i < line2->nfields; ++i)
586         {
587           putchar (output_separator);
588           prfield (i, line2);
589         }
590       putchar ('\n');
591     }
592 }
593
594 /* Print the join of the files in FP1 and FP2.  */
595
596 static void
597 join (FILE *fp1, FILE *fp2)
598 {
599   struct seq seq1, seq2;
600   struct line line;
601   int diff;
602   bool eof1, eof2, checktail;
603
604   /* Read the first line of each file.  */
605   initseq (&seq1);
606   getseq (fp1, &seq1, 1);
607   initseq (&seq2);
608   getseq (fp2, &seq2, 2);
609
610   while (seq1.count && seq2.count)
611     {
612       size_t i;
613       diff = keycmp (&seq1.lines[0], &seq2.lines[0]);
614       if (diff < 0)
615         {
616           if (print_unpairables_1)
617             prjoin (&seq1.lines[0], &uni_blank);
618           advance_seq (fp1, &seq1, true, 1);
619           seen_unpairable = true;
620           continue;
621         }
622       if (diff > 0)
623         {
624           if (print_unpairables_2)
625             prjoin (&uni_blank, &seq2.lines[0]);
626           advance_seq (fp2, &seq2, true, 2);
627           seen_unpairable = true;
628           continue;
629         }
630
631       /* Keep reading lines from file1 as long as they continue to
632          match the current line from file2.  */
633       eof1 = false;
634       do
635         if (!advance_seq (fp1, &seq1, false, 1))
636           {
637             eof1 = true;
638             ++seq1.count;
639             break;
640           }
641       while (!keycmp (&seq1.lines[seq1.count - 1], &seq2.lines[0]));
642
643       /* Keep reading lines from file2 as long as they continue to
644          match the current line from file1.  */
645       eof2 = false;
646       do
647         if (!advance_seq (fp2, &seq2, false, 2))
648           {
649             eof2 = true;
650             ++seq2.count;
651             break;
652           }
653       while (!keycmp (&seq1.lines[0], &seq2.lines[seq2.count - 1]));
654
655       if (print_pairables)
656         {
657           for (i = 0; i < seq1.count - 1; ++i)
658             {
659               size_t j;
660               for (j = 0; j < seq2.count - 1; ++j)
661                 prjoin (&seq1.lines[i], &seq2.lines[j]);
662             }
663         }
664
665       for (i = 0; i < seq1.count - 1; ++i)
666         freeline (&seq1.lines[i]);
667       if (!eof1)
668         {
669           seq1.lines[0] = seq1.lines[seq1.count - 1];
670           seq1.count = 1;
671         }
672       else
673         seq1.count = 0;
674
675       for (i = 0; i < seq2.count - 1; ++i)
676         freeline (&seq2.lines[i]);
677       if (!eof2)
678         {
679           seq2.lines[0] = seq2.lines[seq2.count - 1];
680           seq2.count = 1;
681         }
682       else
683         seq2.count = 0;
684     }
685
686   /* If the user did not specify --check-order, and the we read the
687      tail ends of both inputs to verify that they are in order.  We
688      skip the rest of the tail once we have issued a warning for that
689      file, unless we actually need to print the unpairable lines.  */
690   if (check_input_order != CHECK_ORDER_DISABLED
691       && !(issued_disorder_warning[0] && issued_disorder_warning[1]))
692     checktail = true;
693   else
694     checktail = false;
695
696   if ((print_unpairables_1 || checktail) && seq1.count)
697     {
698       if (print_unpairables_1)
699         prjoin (&seq1.lines[0], &uni_blank);
700       freeline (&seq1.lines[0]);
701       seen_unpairable = true;
702       while (get_line (fp1, &line, 1))
703         {
704           if (print_unpairables_1)
705             prjoin (&line, &uni_blank);
706           freeline (&line);
707           if (issued_disorder_warning[0] && !print_unpairables_1)
708             break;
709         }
710     }
711
712   if ((print_unpairables_2 || checktail) && seq2.count)
713     {
714       if (print_unpairables_2)
715         prjoin (&uni_blank, &seq2.lines[0]);
716       freeline (&seq2.lines[0]);
717       seen_unpairable = true;
718       while (get_line (fp2, &line, 2))
719         {
720           if (print_unpairables_2)
721             prjoin (&uni_blank, &line);
722           freeline (&line);
723           if (issued_disorder_warning[1] && !print_unpairables_2)
724             break;
725         }
726     }
727
728   delseq (&seq1);
729   delseq (&seq2);
730 }
731
732 /* Add a field spec for field FIELD of file FILE to `outlist'.  */
733
734 static void
735 add_field (int file, size_t field)
736 {
737   struct outlist *o;
738
739   assert (file == 0 || file == 1 || file == 2);
740   assert (file != 0 || field == 0);
741
742   o = xmalloc (sizeof *o);
743   o->file = file;
744   o->field = field;
745   o->next = NULL;
746
747   /* Add to the end of the list so the fields are in the right order.  */
748   outlist_end->next = o;
749   outlist_end = o;
750 }
751
752 /* Convert a string of decimal digits, STR (the 1-based join field number),
753    to an integral value.  Upon successful conversion, return one less
754    (the zero-based field number).  Silently convert too-large values
755    to SIZE_MAX - 1.  Otherwise, if a value cannot be converted, give a
756    diagnostic and exit.  */
757
758 static size_t
759 string_to_join_field (char const *str)
760 {
761   size_t result;
762   unsigned long int val;
763   verify (SIZE_MAX <= ULONG_MAX);
764
765   strtol_error s_err = xstrtoul (str, NULL, 10, &val, "");
766   if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val))
767     val = SIZE_MAX;
768   else if (s_err != LONGINT_OK || val == 0)
769     error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str));
770
771   result = val - 1;
772
773   return result;
774 }
775
776 /* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
777    pair.  In S, the field index string is 1-based; *FIELD_INDEX is zero-based.
778    If S is valid, return true.  Otherwise, give a diagnostic and exit.  */
779
780 static void
781 decode_field_spec (const char *s, int *file_index, size_t *field_index)
782 {
783   /* The first character must be 0, 1, or 2.  */
784   switch (s[0])
785     {
786     case '0':
787       if (s[1])
788         {
789           /* `0' must be all alone -- no `.FIELD'.  */
790           error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
791         }
792       *file_index = 0;
793       *field_index = 0;
794       break;
795
796     case '1':
797     case '2':
798       if (s[1] != '.')
799         error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
800       *file_index = s[0] - '0';
801       *field_index = string_to_join_field (s + 2);
802       break;
803
804     default:
805       error (EXIT_FAILURE, 0,
806              _("invalid file number in field spec: %s"), quote (s));
807
808       /* Tell gcc -W -Wall that we can't get beyond this point.
809          This avoids a warning (otherwise legit) that the caller's copies
810          of *file_index and *field_index might be used uninitialized.  */
811       abort ();
812
813       break;
814     }
815 }
816
817 /* Add the comma or blank separated field spec(s) in STR to `outlist'.  */
818
819 static void
820 add_field_list (char *str)
821 {
822   char *p = str;
823
824   do
825     {
826       int file_index;
827       size_t field_index;
828       char const *spec_item = p;
829
830       p = strpbrk (p, ", \t");
831       if (p)
832         *p++ = '\0';
833       decode_field_spec (spec_item, &file_index, &field_index);
834       add_field (file_index, field_index);
835     }
836   while (p);
837 }
838
839 /* Set the join field *VAR to VAL, but report an error if *VAR is set
840    more than once to incompatible values.  */
841
842 static void
843 set_join_field (size_t *var, size_t val)
844 {
845   if (*var != SIZE_MAX && *var != val)
846     {
847       unsigned long int var1 = *var + 1;
848       unsigned long int val1 = val + 1;
849       error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"),
850              var1, val1);
851     }
852   *var = val;
853 }
854
855 /* Status of command-line arguments.  */
856
857 enum operand_status
858   {
859     /* This argument must be an operand, i.e., one of the files to be
860        joined.  */
861     MUST_BE_OPERAND,
862
863     /* This might be the argument of the preceding -j1 or -j2 option,
864        or it might be an operand.  */
865     MIGHT_BE_J1_ARG,
866     MIGHT_BE_J2_ARG,
867
868     /* This might be the argument of the preceding -o option, or it might be
869        an operand.  */
870     MIGHT_BE_O_ARG
871   };
872
873 /* Add NAME to the array of input file NAMES with operand statuses
874    OPERAND_STATUS; currently there are NFILES names in the list.  */
875
876 static void
877 add_file_name (char *name, char *names[2],
878                int operand_status[2], int joption_count[2], int *nfiles,
879                int *prev_optc_status, int *optc_status)
880 {
881   int n = *nfiles;
882
883   if (n == 2)
884     {
885       bool op0 = (operand_status[0] == MUST_BE_OPERAND);
886       char *arg = names[op0];
887       switch (operand_status[op0])
888         {
889         case MUST_BE_OPERAND:
890           error (0, 0, _("extra operand %s"), quote (name));
891           usage (EXIT_FAILURE);
892
893         case MIGHT_BE_J1_ARG:
894           joption_count[0]--;
895           set_join_field (&join_field_1, string_to_join_field (arg));
896           break;
897
898         case MIGHT_BE_J2_ARG:
899           joption_count[1]--;
900           set_join_field (&join_field_2, string_to_join_field (arg));
901           break;
902
903         case MIGHT_BE_O_ARG:
904           add_field_list (arg);
905           break;
906         }
907       if (!op0)
908         {
909           operand_status[0] = operand_status[1];
910           names[0] = names[1];
911         }
912       n = 1;
913     }
914
915   operand_status[n] = *prev_optc_status;
916   names[n] = name;
917   *nfiles = n + 1;
918   if (*prev_optc_status == MIGHT_BE_O_ARG)
919     *optc_status = MIGHT_BE_O_ARG;
920 }
921
922 int
923 main (int argc, char **argv)
924 {
925   int optc_status;
926   int prev_optc_status = MUST_BE_OPERAND;
927   int operand_status[2];
928   int joption_count[2] = { 0, 0 };
929   char *names[2];
930   FILE *fp1, *fp2;
931   int optc;
932   int nfiles = 0;
933   int i;
934
935   initialize_main (&argc, &argv);
936   program_name = argv[0];
937   setlocale (LC_ALL, "");
938   bindtextdomain (PACKAGE, LOCALEDIR);
939   textdomain (PACKAGE);
940   hard_LC_COLLATE = hard_locale (LC_COLLATE);
941
942   atexit (close_stdout);
943   atexit (free_prevline);
944
945   print_pairables = true;
946   seen_unpairable = false;
947   issued_disorder_warning[0] = issued_disorder_warning[1] = false;
948   check_input_order = CHECK_ORDER_DEFAULT;
949
950   while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:",
951                               longopts, NULL))
952          != -1)
953     {
954       optc_status = MUST_BE_OPERAND;
955
956       switch (optc)
957         {
958         case 'v':
959             print_pairables = false;
960             /* Fall through.  */
961
962         case 'a':
963           {
964             unsigned long int val;
965             if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
966                 || (val != 1 && val != 2))
967               error (EXIT_FAILURE, 0,
968                      _("invalid field number: %s"), quote (optarg));
969             if (val == 1)
970               print_unpairables_1 = true;
971             else
972               print_unpairables_2 = true;
973           }
974           break;
975
976         case 'e':
977           if (empty_filler && ! STREQ (empty_filler, optarg))
978             error (EXIT_FAILURE, 0,
979                    _("conflicting empty-field replacement strings"));
980           empty_filler = optarg;
981           break;
982
983         case 'i':
984           ignore_case = true;
985           break;
986
987         case '1':
988           set_join_field (&join_field_1, string_to_join_field (optarg));
989           break;
990
991         case '2':
992           set_join_field (&join_field_2, string_to_join_field (optarg));
993           break;
994
995         case 'j':
996           if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
997               && optarg == argv[optind - 1] + 2)
998             {
999               /* The argument was either "-j1" or "-j2".  */
1000               bool is_j2 = (optarg[0] == '2');
1001               joption_count[is_j2]++;
1002               optc_status = MIGHT_BE_J1_ARG + is_j2;
1003             }
1004           else
1005             {
1006               set_join_field (&join_field_1, string_to_join_field (optarg));
1007               set_join_field (&join_field_2, join_field_1);
1008             }
1009           break;
1010
1011         case 'o':
1012           add_field_list (optarg);
1013           optc_status = MIGHT_BE_O_ARG;
1014           break;
1015
1016         case 't':
1017           {
1018             unsigned char newtab = optarg[0];
1019             if (! newtab)
1020               error (EXIT_FAILURE, 0, _("empty tab"));
1021             if (optarg[1])
1022               {
1023                 if (STREQ (optarg, "\\0"))
1024                   newtab = '\0';
1025                 else
1026                   error (EXIT_FAILURE, 0, _("multi-character tab %s"),
1027                          quote (optarg));
1028               }
1029             if (0 <= tab && tab != newtab)
1030               error (EXIT_FAILURE, 0, _("incompatible tabs"));
1031             tab = newtab;
1032           }
1033           break;
1034
1035         case NOCHECK_ORDER_OPTION:
1036           check_input_order = CHECK_ORDER_DISABLED;
1037           break;
1038
1039         case CHECK_ORDER_OPTION:
1040           check_input_order = CHECK_ORDER_ENABLED;
1041           break;
1042
1043         case 1:         /* Non-option argument.  */
1044           add_file_name (optarg, names, operand_status, joption_count,
1045                          &nfiles, &prev_optc_status, &optc_status);
1046           break;
1047
1048         case_GETOPT_HELP_CHAR;
1049
1050         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1051
1052         default:
1053           usage (EXIT_FAILURE);
1054         }
1055
1056       prev_optc_status = optc_status;
1057     }
1058
1059   /* Process any operands after "--".  */
1060   prev_optc_status = MUST_BE_OPERAND;
1061   while (optind < argc)
1062     add_file_name (argv[optind++], names, operand_status, joption_count,
1063                    &nfiles, &prev_optc_status, &optc_status);
1064
1065   if (nfiles != 2)
1066     {
1067       if (nfiles == 0)
1068         error (0, 0, _("missing operand"));
1069       else
1070         error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
1071       usage (EXIT_FAILURE);
1072     }
1073
1074   /* If "-j1" was specified and it turns out not to have had an argument,
1075      treat it as "-j 1".  Likewise for -j2.  */
1076   for (i = 0; i < 2; i++)
1077     if (joption_count[i] != 0)
1078       {
1079         set_join_field (&join_field_1, i);
1080         set_join_field (&join_field_2, i);
1081       }
1082
1083   if (join_field_1 == SIZE_MAX)
1084     join_field_1 = 0;
1085   if (join_field_2 == SIZE_MAX)
1086     join_field_2 = 0;
1087
1088   fp1 = STREQ (names[0], "-") ? stdin : fopen (names[0], "r");
1089   if (!fp1)
1090     error (EXIT_FAILURE, errno, "%s", names[0]);
1091   fp2 = STREQ (names[1], "-") ? stdin : fopen (names[1], "r");
1092   if (!fp2)
1093     error (EXIT_FAILURE, errno, "%s", names[1]);
1094   if (fp1 == fp2)
1095     error (EXIT_FAILURE, errno, _("both files cannot be standard input"));
1096   join (fp1, fp2);
1097
1098   if (fclose (fp1) != 0)
1099     error (EXIT_FAILURE, errno, "%s", names[0]);
1100   if (fclose (fp2) != 0)
1101     error (EXIT_FAILURE, errno, "%s", names[1]);
1102
1103   if (issued_disorder_warning[0] || issued_disorder_warning[1])
1104     exit (EXIT_FAILURE);
1105   else
1106     exit (EXIT_SUCCESS);
1107 }