csplit cleanup.
[platform/upstream/coreutils.git] / src / csplit.c
1 /* csplit - split a file into sections determined by context lines
2    Copyright (C) 91, 1995-2003 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 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Written by Stuart Kemp, cpsrk@groper.jcu.edu.au.
19    Modified by David MacKenzie, djm@gnu.ai.mit.edu. */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <getopt.h>
25 #include <sys/types.h>
26 #include <signal.h>
27
28 #include "system.h"
29
30 #include <regex.h>
31
32 #include "error.h"
33 #include "inttostr.h"
34 #include "safe-read.h"
35 #include "xstrtol.h"
36
37 /* The official name of this program (e.g., no `g' prefix).  */
38 #define PROGRAM_NAME "csplit"
39
40 #define WRITTEN_BY _("Written by Stuart Kemp and David MacKenzie.")
41
42 /* Increment size of area for control records. */
43 #define ALLOC_SIZE 20
44
45 /* The default prefix for output file names. */
46 #define DEFAULT_PREFIX  "xx"
47
48 /* A compiled pattern arg. */
49 struct control
50 {
51   char *regexpr;                /* Non-compiled regular expression. */
52   struct re_pattern_buffer re_compiled; /* Compiled regular expression. */
53   intmax_t offset;              /* Offset from regexp to split at. */
54   uintmax_t lines_required;     /* Number of lines required. */
55   uintmax_t repeat;             /* Repeat count. */
56   int argnum;                   /* ARGV index. */
57   bool repeat_forever;          /* True if `*' used as a repeat count. */
58   bool ignore;                  /* If true, produce no output (for regexp). */
59 };
60
61 /* Initial size of data area in buffers. */
62 #define START_SIZE      8191
63
64 /* Increment size for data area. */
65 #define INCR_SIZE       2048
66
67 /* Number of lines kept in each node in line list. */
68 #define CTRL_SIZE       80
69
70 #ifdef DEBUG
71 /* Some small values to test the algorithms. */
72 # define START_SIZE     200
73 # define INCR_SIZE      10
74 # define CTRL_SIZE      1
75 #endif
76
77 /* A string with a length count. */
78 struct cstring
79 {
80   size_t len;
81   char *str;
82 };
83
84 /* Pointers to the beginnings of lines in the buffer area.
85    These structures are linked together if needed. */
86 struct line
87 {
88   unsigned int used;            /* Number of offsets used in this struct. */
89   unsigned int insert_index;    /* Next offset to use when inserting line. */
90   unsigned int retrieve_index;  /* Next index to use when retrieving line. */
91   struct cstring starts[CTRL_SIZE]; /* Lines in the data area. */
92   struct line *next;            /* Next in linked list. */
93 };
94
95 /* The structure to hold the input lines.
96    Contains a pointer to the data area and a list containing
97    pointers to the individual lines. */
98 struct buffer_record
99 {
100   size_t bytes_alloc;           /* Size of the buffer area. */
101   size_t bytes_used;            /* Bytes used in the buffer area. */
102   uintmax_t start_line;         /* First line number in this buffer. */
103   uintmax_t first_available;    /* First line that can be retrieved. */
104   size_t num_lines;             /* Number of complete lines in this buffer. */
105   char *buffer;                 /* Data area. */
106   struct line *line_start;      /* Head of list of pointers to lines. */
107   struct line *curr_line;       /* The line start record currently in use. */
108   struct buffer_record *next;
109 };
110
111 static void close_output_file (void);
112 static void create_output_file (void);
113 static void delete_all_files (void);
114 static void save_line_to_file (const struct cstring *line);
115 void usage (int status);
116
117 /* The name this program was run with. */
118 char *program_name;
119
120 /* Input file descriptor. */
121 static int input_desc = 0;
122
123 /* Start of buffer list. */
124 static struct buffer_record *head = NULL;
125
126 /* Partially read line. */
127 static char *hold_area = NULL;
128
129 /* Number of bytes in `hold_area'. */
130 static size_t hold_count = 0;
131
132 /* Number of the last line in the buffers. */
133 static uintmax_t last_line_number = 0;
134
135 /* Number of the line currently being examined. */
136 static uintmax_t current_line = 0;
137
138 /* If true, we have read EOF. */
139 static bool have_read_eof = false;
140
141 /* Name of output files. */
142 static char *filename_space = NULL;
143
144 /* Prefix part of output file names. */
145 static char *prefix = NULL;
146
147 /* Suffix part of output file names. */
148 static char *suffix = NULL;
149
150 /* Number of digits to use in output file names. */
151 static int digits = 2;
152
153 /* Number of files created so far. */
154 static unsigned int files_created = 0;
155
156 /* Number of bytes written to current file. */
157 static uintmax_t bytes_written;
158
159 /* Output file pointer. */
160 static FILE *output_stream = NULL;
161
162 /* Output file name. */
163 static char *output_filename = NULL;
164
165 /* Perhaps it would be cleaner to pass arg values instead of indexes. */
166 static char **global_argv;
167
168 /* If true, do not print the count of bytes in each output file. */
169 static bool suppress_count;
170
171 /* If true, remove output files on error. */
172 static bool remove_files;
173
174 /* If true, remove all output files which have a zero length. */
175 static bool elide_empty_files;
176
177 /* The compiled pattern arguments, which determine how to split
178    the input file. */
179 static struct control *controls;
180
181 /* Number of elements in `controls'. */
182 static size_t control_used;
183
184 static struct option const longopts[] =
185 {
186   {"digits", required_argument, NULL, 'n'},
187   {"quiet", no_argument, NULL, 'q'},
188   {"silent", no_argument, NULL, 's'},
189   {"keep-files", no_argument, NULL, 'k'},
190   {"elide-empty-files", no_argument, NULL, 'z'},
191   {"prefix", required_argument, NULL, 'f'},
192   {"suffix-format", required_argument, NULL, 'b'},
193   {GETOPT_HELP_OPTION_DECL},
194   {GETOPT_VERSION_OPTION_DECL},
195   {NULL, 0, NULL, 0}
196 };
197
198 /* Optionally remove files created so far; then exit.
199    Called when an error detected. */
200
201 static void
202 cleanup (void)
203 {
204   close_output_file ();
205
206   if (remove_files)
207     delete_all_files ();
208 }
209
210 static void
211 cleanup_fatal (void)
212 {
213   cleanup ();
214   exit (EXIT_FAILURE);
215 }
216
217 static RETSIGTYPE
218 interrupt_handler (int sig)
219 {
220 #ifdef SA_NOCLDSTOP
221   struct sigaction sigact;
222
223   sigact.sa_handler = SIG_DFL;
224   sigemptyset (&sigact.sa_mask);
225   sigact.sa_flags = 0;
226   sigaction (sig, &sigact, NULL);
227 #else
228   signal (sig, SIG_DFL);
229 #endif
230   cleanup ();
231   raise (sig);
232 }
233
234 /* Keep track of NUM bytes of a partial line in buffer START.
235    These bytes will be retrieved later when another large buffer is read.
236    It is not necessary to create a new buffer for these bytes; instead,
237    we keep a pointer to the existing buffer.  This buffer *is* on the
238    free list, and when the next buffer is obtained from this list
239    (even if it is this one), these bytes will be placed at the
240    start of the new buffer. */
241
242 static void
243 save_to_hold_area (char *start, size_t num)
244 {
245   hold_area = start;
246   hold_count = num;
247 }
248
249 /* Read up to MAX_N_BYTES bytes from the input stream into DEST.
250    Return the number of bytes read. */
251
252 static size_t
253 read_input (char *dest, size_t max_n_bytes)
254 {
255   size_t bytes_read;
256
257   if (max_n_bytes == 0)
258     return 0;
259
260   bytes_read = safe_read (input_desc, dest, max_n_bytes);
261
262   if (bytes_read == 0)
263     have_read_eof = true;
264
265   if (bytes_read == SAFE_READ_ERROR)
266     {
267       error (0, errno, _("read error"));
268       cleanup_fatal ();
269     }
270
271   return bytes_read;
272 }
273
274 /* Initialize existing line record P. */
275
276 static void
277 clear_line_control (struct line *p)
278 {
279   p->used = 0;
280   p->insert_index = 0;
281   p->retrieve_index = 0;
282 }
283
284 /* Return a new, initialized line record. */
285
286 static struct line *
287 new_line_control (void)
288 {
289   struct line *p = xmalloc (sizeof *p);
290
291   p->next = NULL;
292   clear_line_control (p);
293
294   return p;
295 }
296
297 /* Record LINE_START, which is the address of the start of a line
298    of length LINE_LEN in the large buffer, in the lines buffer of B. */
299
300 static void
301 keep_new_line (struct buffer_record *b, char *line_start, size_t line_len)
302 {
303   struct line *l;
304
305   /* If there is no existing area to keep line info, get some. */
306   if (b->line_start == NULL)
307     b->line_start = b->curr_line = new_line_control ();
308
309   /* If existing area for lines is full, get more. */
310   if (b->curr_line->used == CTRL_SIZE)
311     {
312       b->curr_line->next = new_line_control ();
313       b->curr_line = b->curr_line->next;
314     }
315
316   l = b->curr_line;
317
318   /* Record the start of the line, and update counters. */
319   l->starts[l->insert_index].str = line_start;
320   l->starts[l->insert_index].len = line_len;
321   l->used++;
322   l->insert_index++;
323 }
324
325 /* Scan the buffer in B for newline characters
326    and record the line start locations and lengths in B.
327    Return the number of lines found in this buffer.
328
329    There may be an incomplete line at the end of the buffer;
330    a pointer is kept to this area, which will be used when
331    the next buffer is filled. */
332
333 static size_t
334 record_line_starts (struct buffer_record *b)
335 {
336   char *line_start;             /* Start of current line. */
337   char *line_end;               /* End of each line found. */
338   size_t bytes_left;            /* Length of incomplete last line. */
339   size_t lines;                 /* Number of lines found. */
340   size_t line_length;           /* Length of each line found. */
341
342   if (b->bytes_used == 0)
343     return 0;
344
345   lines = 0;
346   line_start = b->buffer;
347   bytes_left = b->bytes_used;
348
349   for (;;)
350     {
351       line_end = memchr (line_start, '\n', bytes_left);
352       if (line_end == NULL)
353         break;
354       line_length = line_end - line_start + 1;
355       keep_new_line (b, line_start, line_length);
356       bytes_left -= line_length;
357       line_start = line_end + 1;
358       lines++;
359     }
360
361   /* Check for an incomplete last line. */
362   if (bytes_left)
363     {
364       if (have_read_eof)
365         {
366           keep_new_line (b, line_start, bytes_left);
367           lines++;
368         }
369       else
370         save_to_hold_area (line_start, bytes_left);
371     }
372
373   b->num_lines = lines;
374   b->first_available = b->start_line = last_line_number + 1;
375   last_line_number += lines;
376
377   return lines;
378 }
379
380 /* Return a new buffer with room to store SIZE bytes, plus
381    an extra byte for safety. */
382
383 static struct buffer_record *
384 create_new_buffer (size_t size)
385 {
386   struct buffer_record *new_buffer = xmalloc (sizeof *new_buffer);
387
388   new_buffer->buffer = xmalloc (size + 1);
389
390   new_buffer->bytes_alloc = size;
391   new_buffer->line_start = new_buffer->curr_line = NULL;
392
393   return new_buffer;
394 }
395
396 /* Return a new buffer of at least MINSIZE bytes.  If a buffer of at
397    least that size is currently free, use it, otherwise create a new one. */
398
399 static struct buffer_record *
400 get_new_buffer (size_t min_size)
401 {
402   struct buffer_record *new_buffer; /* Buffer to return. */
403   size_t alloc_size;    /* Actual size that will be requested. */
404
405   alloc_size = START_SIZE;
406   if (alloc_size < min_size)
407     {
408       size_t s = min_size - alloc_size + INCR_SIZE - 1;
409       alloc_size += s - s % INCR_SIZE;
410     }
411
412   new_buffer = create_new_buffer (alloc_size);
413
414   new_buffer->num_lines = 0;
415   new_buffer->bytes_used = 0;
416   new_buffer->start_line = new_buffer->first_available = last_line_number + 1;
417   new_buffer->next = NULL;
418
419   return new_buffer;
420 }
421
422 static void
423 free_buffer (struct buffer_record *buf)
424 {
425   free (buf->buffer);
426 }
427
428 /* Append buffer BUF to the linked list of buffers that contain
429    some data yet to be processed. */
430
431 static void
432 save_buffer (struct buffer_record *buf)
433 {
434   struct buffer_record *p;
435
436   buf->next = NULL;
437   buf->curr_line = buf->line_start;
438
439   if (head == NULL)
440     head = buf;
441   else
442     {
443       for (p = head; p->next; p = p->next)
444         /* Do nothing. */ ;
445       p->next = buf;
446     }
447 }
448
449 /* Fill a buffer of input.
450
451    Set the initial size of the buffer to a default.
452    Fill the buffer (from the hold area and input stream)
453    and find the individual lines.
454    If no lines are found (the buffer is too small to hold the next line),
455    release the current buffer (whose contents would have been put in the
456    hold area) and repeat the process with another large buffer until at least
457    one entire line has been read.
458
459    Return true if a new buffer was obtained, otherwise false
460    (in which case end-of-file must have been encountered). */
461
462 static bool
463 load_buffer (void)
464 {
465   struct buffer_record *b;
466   size_t bytes_wanted = START_SIZE; /* Minimum buffer size. */
467   size_t bytes_avail;           /* Size of new buffer created. */
468   size_t lines_found;           /* Number of lines in this new buffer. */
469   char *p;                      /* Place to load into buffer. */
470
471   if (have_read_eof)
472     return false;
473
474   /* We must make the buffer at least as large as the amount of data
475      in the partial line left over from the last call. */
476   if (bytes_wanted < hold_count)
477     bytes_wanted = hold_count;
478
479   do
480     {
481       b = get_new_buffer (bytes_wanted);
482       bytes_avail = b->bytes_alloc; /* Size of buffer returned. */
483       p = b->buffer;
484
485       /* First check the `holding' area for a partial line. */
486       if (hold_count)
487         {
488           if (p != hold_area)
489             memcpy (p, hold_area, hold_count);
490           p += hold_count;
491           b->bytes_used += hold_count;
492           bytes_avail -= hold_count;
493           hold_count = 0;
494         }
495
496       b->bytes_used += read_input (p, bytes_avail);
497
498       lines_found = record_line_starts (b);
499       bytes_wanted = b->bytes_alloc * 2;
500       if (!lines_found)
501         free_buffer (b);
502     }
503   while (!lines_found && !have_read_eof);
504
505   if (lines_found)
506     save_buffer (b);
507
508   return lines_found != 0;
509 }
510
511 /* Return the line number of the first line that has not yet been retrieved. */
512
513 static uintmax_t
514 get_first_line_in_buffer (void)
515 {
516   if (head == NULL && !load_buffer ())
517     error (EXIT_FAILURE, errno, _("input disappeared"));
518
519   return head->first_available;
520 }
521
522 /* Return a pointer to the logical first line in the buffer and make the
523    next line the logical first line.
524    Return NULL if there is no more input. */
525
526 static struct cstring *
527 remove_line (void)
528 {
529   struct cstring *line;         /* Return value. */
530   struct line *l;               /* For convenience. */
531
532   if (head == NULL && !load_buffer ())
533     return NULL;
534
535   if (current_line < head->first_available)
536     current_line = head->first_available;
537
538   ++(head->first_available);
539
540   l = head->curr_line;
541
542   line = &l->starts[l->retrieve_index];
543
544   /* Advance index to next line. */
545   if (++l->retrieve_index == l->used)
546     {
547       /* Go on to the next line record. */
548       head->curr_line = l->next;
549       if (head->curr_line == NULL || head->curr_line->used == 0)
550         {
551           /* Go on to the next data block. */
552           struct buffer_record *b = head;
553           head = head->next;
554           free_buffer (b);
555         }
556     }
557
558   return line;
559 }
560
561 /* Search the buffers for line LINENUM, reading more input if necessary.
562    Return a pointer to the line, or NULL if it is not found in the file. */
563
564 static struct cstring *
565 find_line (uintmax_t linenum)
566 {
567   struct buffer_record *b;
568
569   if (head == NULL && !load_buffer ())
570     return NULL;
571
572   if (linenum < head->start_line)
573     return NULL;
574
575   for (b = head;;)
576     {
577       if (linenum < b->start_line + b->num_lines)
578         {
579           /* The line is in this buffer. */
580           struct line *l;
581           size_t offset;        /* How far into the buffer the line is. */
582
583           l = b->line_start;
584           offset = linenum - b->start_line;
585           /* Find the control record. */
586           while (offset >= CTRL_SIZE)
587             {
588               l = l->next;
589               offset -= CTRL_SIZE;
590             }
591           return &l->starts[offset];
592         }
593       if (b->next == NULL && !load_buffer ())
594         return NULL;
595       b = b->next;              /* Try the next data block. */
596     }
597 }
598
599 /* Return true if at least one more line is available for input. */
600
601 static bool
602 no_more_lines (void)
603 {
604   return find_line (current_line + 1) == NULL;
605 }
606
607 /* Set the name of the input file to NAME and open it. */
608
609 static void
610 set_input_file (const char *name)
611 {
612   if (STREQ (name, "-"))
613     input_desc = 0;
614   else
615     {
616       input_desc = open (name, O_RDONLY);
617       if (input_desc < 0)
618         error (EXIT_FAILURE, errno, "%s", name);
619     }
620 }
621
622 /* Write all lines from the beginning of the buffer up to, but
623    not including, line LAST_LINE, to the current output file.
624    If IGNORE is true, do not output lines selected here.
625    ARGNUM is the index in ARGV of the current pattern. */
626
627 static void
628 write_to_file (uintmax_t last_line, bool ignore, int argnum)
629 {
630   struct cstring *line;
631   uintmax_t first_line;         /* First available input line. */
632   uintmax_t lines;              /* Number of lines to output. */
633   uintmax_t i;
634
635   first_line = get_first_line_in_buffer ();
636
637   if (first_line > last_line)
638     {
639       error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
640       cleanup_fatal ();
641     }
642
643   lines = last_line - first_line;
644
645   for (i = 0; i < lines; i++)
646     {
647       line = remove_line ();
648       if (line == NULL)
649         {
650           error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
651           cleanup_fatal ();
652         }
653       if (!ignore)
654         save_line_to_file (line);
655     }
656 }
657
658 /* Output any lines left after all regexps have been processed. */
659
660 static void
661 dump_rest_of_file (void)
662 {
663   struct cstring *line;
664
665   while ((line = remove_line ()) != NULL)
666     save_line_to_file (line);
667 }
668
669 /* Handle an attempt to read beyond EOF under the control of record P,
670    on iteration REPETITION if nonzero. */
671
672 static void
673 handle_line_error (const struct control *p, uintmax_t repetition)
674 {
675   char buf[INT_BUFSIZE_BOUND (uintmax_t)];
676
677   fprintf (stderr, _("%s: `%s': line number out of range"),
678            program_name, umaxtostr (p->lines_required, buf));
679   if (repetition)
680     fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
681   else
682     fprintf (stderr, "\n");
683
684   cleanup_fatal ();
685 }
686
687 /* Determine the line number that marks the end of this file,
688    then get those lines and save them to the output file.
689    P is the control record.
690    REPETITION is the repetition number. */
691
692 static void
693 process_line_count (const struct control *p, uintmax_t repetition)
694 {
695   uintmax_t linenum;
696   uintmax_t last_line_to_save = p->lines_required * (repetition + 1);
697   struct cstring *line;
698
699   create_output_file ();
700
701   linenum = get_first_line_in_buffer ();
702
703   while (linenum++ < last_line_to_save)
704     {
705       line = remove_line ();
706       if (line == NULL)
707         handle_line_error (p, repetition);
708       save_line_to_file (line);
709     }
710
711   close_output_file ();
712
713   /* Ensure that the line number specified is not 1 greater than
714      the number of lines in the file. */
715   if (no_more_lines ())
716     handle_line_error (p, repetition);
717 }
718
719 static void
720 regexp_error (struct control *p, uintmax_t repetition, bool ignore)
721 {
722   fprintf (stderr, _("%s: `%s': match not found"),
723            program_name, global_argv[p->argnum]);
724
725   if (repetition)
726     {
727       char buf[INT_BUFSIZE_BOUND (uintmax_t)];
728       fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
729     }
730   else
731     fprintf (stderr, "\n");
732
733   if (!ignore)
734     {
735       dump_rest_of_file ();
736       close_output_file ();
737     }
738   cleanup_fatal ();
739 }
740
741 /* Read the input until a line matches the regexp in P, outputting
742    it unless P->IGNORE is true.
743    REPETITION is this repeat-count; 0 means the first time. */
744
745 static void
746 process_regexp (struct control *p, uintmax_t repetition)
747 {
748   struct cstring *line;         /* From input file. */
749   size_t line_len;              /* To make "$" in regexps work. */
750   uintmax_t break_line;         /* First line number of next file. */
751   bool ignore = p->ignore;      /* If true, skip this section. */
752   int ret;
753
754   if (!ignore)
755     create_output_file ();
756
757   /* If there is no offset for the regular expression, or
758      it is positive, then it is not necessary to buffer the lines. */
759
760   if (p->offset >= 0)
761     {
762       for (;;)
763         {
764           line = find_line (++current_line);
765           if (line == NULL)
766             {
767               if (p->repeat_forever)
768                 {
769                   if (!ignore)
770                     {
771                       dump_rest_of_file ();
772                       close_output_file ();
773                     }
774                   exit (EXIT_SUCCESS);
775                 }
776               else
777                 regexp_error (p, repetition, ignore);
778             }
779           line_len = line->len;
780           if (line->str[line_len - 1] == '\n')
781             line_len--;
782           ret = re_search (&p->re_compiled, line->str, line_len,
783                            0, line_len, NULL);
784           if (ret == -2)
785             {
786               error (0, 0, _("error in regular expression search"));
787               cleanup_fatal ();
788             }
789           if (ret == -1)
790             {
791               line = remove_line ();
792               if (!ignore)
793                 save_line_to_file (line);
794             }
795           else
796             break;
797         }
798     }
799   else
800     {
801       /* Buffer the lines. */
802       for (;;)
803         {
804           line = find_line (++current_line);
805           if (line == NULL)
806             {
807               if (p->repeat_forever)
808                 {
809                   if (!ignore)
810                     {
811                       dump_rest_of_file ();
812                       close_output_file ();
813                     }
814                   exit (EXIT_SUCCESS);
815                 }
816               else
817                 regexp_error (p, repetition, ignore);
818             }
819           line_len = line->len;
820           if (line->str[line_len - 1] == '\n')
821             line_len--;
822           ret = re_search (&p->re_compiled, line->str, line_len,
823                            0, line_len, NULL);
824           if (ret == -2)
825             {
826               error (0, 0, _("error in regular expression search"));
827               cleanup_fatal ();
828             }
829           if (ret >= 0)
830             break;
831         }
832     }
833
834   /* Account for any offset from this regexp. */
835   break_line = current_line + p->offset;
836
837   write_to_file (break_line, ignore, p->argnum);
838
839   if (!ignore)
840     close_output_file ();
841
842   if (p->offset > 0)
843     current_line = break_line;
844 }
845
846 /* Split the input file according to the control records we have built. */
847
848 static void
849 split_file (void)
850 {
851   size_t i;
852
853   for (i = 0; i < control_used; i++)
854     {
855       uintmax_t j;
856       if (controls[i].regexpr)
857         {
858           for (j = 0; (controls[i].repeat_forever
859                        || j <= controls[i].repeat); j++)
860             process_regexp (&controls[i], j);
861         }
862       else
863         {
864           for (j = 0; (controls[i].repeat_forever
865                        || j <= controls[i].repeat); j++)
866             process_line_count (&controls[i], j);
867         }
868     }
869
870   create_output_file ();
871   dump_rest_of_file ();
872   close_output_file ();
873 }
874
875 /* Return the name of output file number NUM. */
876
877 static char *
878 make_filename (unsigned int num)
879 {
880   strcpy (filename_space, prefix);
881   if (suffix)
882     sprintf (filename_space+strlen(prefix), suffix, num);
883   else
884     sprintf (filename_space+strlen(prefix), "%0*u", digits, num);
885   return filename_space;
886 }
887
888 /* Create the next output file. */
889
890 static void
891 create_output_file (void)
892 {
893   output_filename = make_filename (files_created);
894   output_stream = fopen (output_filename, "w");
895   if (output_stream == NULL)
896     {
897       error (0, errno, "%s", output_filename);
898       cleanup_fatal ();
899     }
900   files_created++;
901   bytes_written = 0;
902 }
903
904 /* Delete all the files we have created. */
905
906 static void
907 delete_all_files (void)
908 {
909   unsigned int i;
910
911   for (i = 0; i < files_created; i++)
912     {
913       const char *name = make_filename (i);
914       if (unlink (name))
915         error (0, errno, "%s", name);
916     }
917 }
918
919 /* Close the current output file and print the count
920    of characters in this file. */
921
922 static void
923 close_output_file (void)
924 {
925   if (output_stream)
926     {
927       if (ferror (output_stream))
928         {
929           error (0, 0, _("write error for `%s'"), output_filename);
930           output_stream = NULL;
931           cleanup_fatal ();
932         }
933       if (fclose (output_stream) != 0)
934         {
935           error (0, errno, "%s", output_filename);
936           output_stream = NULL;
937           cleanup_fatal ();
938         }
939       if (bytes_written == 0 && elide_empty_files)
940         {
941           if (unlink (output_filename))
942             error (0, errno, "%s", output_filename);
943           files_created--;
944         }
945       else
946         {
947           /* FIXME: if we write to stdout here, we have to close stdout
948              and check for errors.  */
949           if (!suppress_count)
950             {
951               char buf[INT_BUFSIZE_BOUND (uintmax_t)];
952               fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
953             }
954         }
955       output_stream = NULL;
956     }
957 }
958
959 /* Save line LINE to the output file and
960    increment the character count for the current file. */
961
962 static void
963 save_line_to_file (const struct cstring *line)
964 {
965   fwrite (line->str, sizeof (char), line->len, output_stream);
966   bytes_written += line->len;
967 }
968
969 /* Return a new, initialized control record. */
970
971 static struct control *
972 new_control_record (void)
973 {
974   static size_t control_allocated = 0; /* Total space allocated. */
975   struct control *p;
976
977   if (control_used == control_allocated)
978     {
979       control_allocated += ALLOC_SIZE;
980       controls = xrealloc (controls, control_allocated * sizeof *controls);
981     }
982   p = &controls[control_used++];
983   p->regexpr = NULL;
984   p->repeat = 0;
985   p->repeat_forever = false;
986   p->lines_required = 0;
987   p->offset = 0;
988   return p;
989 }
990
991 /* Check if there is a numeric offset after a regular expression.
992    STR is the entire command line argument.
993    P is the control record for this regular expression.
994    NUM is the numeric part of STR. */
995
996 static void
997 check_for_offset (struct control *p, const char *str, const char *num)
998 {
999   if (xstrtoimax (num, NULL, 10, &p->offset, "") != LONGINT_OK)
1000     error (EXIT_FAILURE, 0, _("%s: integer expected after delimiter"), str);
1001 }
1002
1003 /* Given that the first character of command line arg STR is '{',
1004    make sure that the rest of the string is a valid repeat count
1005    and store its value in P.
1006    ARGNUM is the ARGV index of STR. */
1007
1008 static void
1009 parse_repeat_count (int argnum, struct control *p, char *str)
1010 {
1011   uintmax_t val;
1012   char *end;
1013
1014   end = str + strlen (str) - 1;
1015   if (*end != '}')
1016     error (EXIT_FAILURE, 0, _("%s: `}' is required in repeat count"), str);
1017   *end = '\0';
1018
1019   if (str+1 == end-1 && *(str+1) == '*')
1020     p->repeat_forever = true;
1021   else
1022     {
1023       if (xstrtoumax (str + 1, NULL, 10, &val, "") != LONGINT_OK)
1024         {
1025           error (EXIT_FAILURE, 0,
1026                  _("%s}: integer required between `{' and `}'"),
1027                  global_argv[argnum]);
1028         }
1029       p->repeat = val;
1030     }
1031
1032   *end = '}';
1033 }
1034
1035 /* Extract the regular expression from STR and check for a numeric offset.
1036    STR should start with the regexp delimiter character.
1037    Return a new control record for the regular expression.
1038    ARGNUM is the ARGV index of STR.
1039    Unless IGNORE is true, mark these lines for output. */
1040
1041 static struct control *
1042 extract_regexp (int argnum, bool ignore, char *str)
1043 {
1044   size_t len;                   /* Number of bytes in this regexp. */
1045   char delim = *str;
1046   char *closing_delim;
1047   struct control *p;
1048   const char *err;
1049
1050   closing_delim = strrchr (str + 1, delim);
1051   if (closing_delim == NULL)
1052     error (EXIT_FAILURE, 0,
1053            _("%s: closing delimiter `%c' missing"), str, delim);
1054
1055   len = closing_delim - str - 1;
1056   p = new_control_record ();
1057   p->argnum = argnum;
1058   p->ignore = ignore;
1059
1060   p->regexpr = xmalloc (len + 1);
1061   strncpy (p->regexpr, str + 1, len);
1062   p->re_compiled.allocated = len * 2;
1063   p->re_compiled.buffer = xmalloc (p->re_compiled.allocated);
1064   p->re_compiled.fastmap = xmalloc (1 << CHAR_BIT);
1065   p->re_compiled.translate = 0;
1066   err = re_compile_pattern (p->regexpr, len, &p->re_compiled);
1067   if (err)
1068     {
1069       error (0, 0, _("%s: invalid regular expression: %s"), str, err);
1070       cleanup_fatal ();
1071     }
1072
1073   if (closing_delim[1])
1074     check_for_offset (p, str, closing_delim + 1);
1075
1076   return p;
1077 }
1078
1079 /* Extract the break patterns from args START through ARGC - 1 of ARGV.
1080    After each pattern, check if the next argument is a repeat count. */
1081
1082 static void
1083 parse_patterns (int argc, int start, char **argv)
1084 {
1085   int i;                        /* Index into ARGV. */
1086   struct control *p;            /* New control record created. */
1087   uintmax_t val;
1088   static uintmax_t last_val = 0;
1089
1090   for (i = start; i < argc; i++)
1091     {
1092       if (*argv[i] == '/' || *argv[i] == '%')
1093         {
1094           p = extract_regexp (i, *argv[i] == '%', argv[i]);
1095         }
1096       else
1097         {
1098           p = new_control_record ();
1099           p->argnum = i;
1100
1101           if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
1102             error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
1103           if (val == 0)
1104             error (EXIT_FAILURE, 0,
1105                    _("%s: line number must be greater than zero"),
1106                    argv[i]);
1107           if (val < last_val)
1108             {
1109               char buf[INT_BUFSIZE_BOUND (uintmax_t)];
1110               error (EXIT_FAILURE, 0,
1111                _("line number `%s' is smaller than preceding line number, %s"),
1112                      argv[i], umaxtostr (last_val, buf));
1113             }
1114
1115           if (val == last_val)
1116             error (0, 0,
1117            _("warning: line number `%s' is the same as preceding line number"),
1118                    argv[i]);
1119
1120           last_val = val;
1121
1122           p->lines_required = val;
1123         }
1124
1125       if (i + 1 < argc && *argv[i + 1] == '{')
1126         {
1127           /* We have a repeat count. */
1128           i++;
1129           parse_repeat_count (i, p, argv[i]);
1130         }
1131     }
1132 }
1133
1134 static unsigned int
1135 get_format_flags (char **format_ptr)
1136 {
1137   unsigned int count = 0;
1138
1139   for (; **format_ptr; (*format_ptr)++)
1140     {
1141       switch (**format_ptr)
1142         {
1143         case '-':
1144           break;
1145
1146         case '+':
1147         case ' ':
1148           count |= 1;
1149           break;
1150
1151         case '#':
1152           count |= 2;   /* Allow for 0x prefix preceding an `x' conversion.  */
1153           break;
1154
1155         default:
1156           return count;
1157         }
1158     }
1159   return count;
1160 }
1161
1162 static size_t
1163 get_format_width (char **format_ptr)
1164 {
1165   unsigned long int val = 0;
1166
1167   if (ISDIGIT (**format_ptr)
1168       && (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
1169           || SIZE_MAX < val))
1170     error (EXIT_FAILURE, 0, _("invalid format width"));
1171
1172   /* Allow for enough octal digits to represent the value of UINT_MAX,
1173      even if the field width is less than that.  */
1174   return MAX (val, (sizeof (unsigned int) * CHAR_BIT + 2) / 3);
1175 }
1176
1177 static size_t
1178 get_format_prec (char **format_ptr)
1179 {
1180   if (**format_ptr != '.')
1181     return 0;
1182   (*format_ptr)++;
1183
1184   if (! ISDIGIT (**format_ptr))
1185     return 0;
1186   else
1187     {
1188       unsigned long int val;
1189       if (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
1190           || SIZE_MAX < val)
1191         error (EXIT_FAILURE, 0, _("invalid format precision"));
1192       return val;
1193     }
1194 }
1195
1196 static void
1197 get_format_conv_type (char **format_ptr)
1198 {
1199   unsigned char ch = *(*format_ptr)++;
1200
1201   switch (ch)
1202     {
1203     case 'd':
1204     case 'i':
1205     case 'o':
1206     case 'u':
1207     case 'x':
1208     case 'X':
1209       break;
1210
1211     case 0:
1212       error (EXIT_FAILURE, 0, _("missing conversion specifier in suffix"));
1213       break;
1214
1215     default:
1216       if (ISPRINT (ch))
1217         error (EXIT_FAILURE, 0,
1218                _("invalid conversion specifier in suffix: %c"), ch);
1219       else
1220         error (EXIT_FAILURE, 0,
1221                _("invalid conversion specifier in suffix: \\%.3o"), ch);
1222     }
1223 }
1224
1225 static size_t
1226 max_out (char *format)
1227 {
1228   size_t out_count = 0;
1229   bool percent = false;
1230
1231   while (*format)
1232     {
1233       if (*format++ != '%')
1234         out_count++;
1235       else if (*format == '%')
1236         {
1237           format++;
1238           out_count++;
1239         }
1240       else
1241         {
1242           if (percent)
1243             error (EXIT_FAILURE, 0,
1244                    _("too many %% conversion specifications in suffix"));
1245           percent = true;
1246           out_count += get_format_flags (&format);
1247           {
1248             size_t width = get_format_width (&format);
1249             size_t prec = get_format_prec (&format);
1250
1251             out_count += MAX (width, prec);
1252           }
1253           get_format_conv_type (&format);
1254         }
1255     }
1256
1257   if (! percent)
1258     error (EXIT_FAILURE, 0,
1259            _("missing %% conversion specification in suffix"));
1260
1261   return out_count;
1262 }
1263
1264 int
1265 main (int argc, char **argv)
1266 {
1267   int optc;
1268   unsigned long int val;
1269 #ifdef SA_NOCLDSTOP
1270   struct sigaction oldact, newact;
1271 #endif
1272
1273   initialize_main (&argc, &argv);
1274   program_name = argv[0];
1275   setlocale (LC_ALL, "");
1276   bindtextdomain (PACKAGE, LOCALEDIR);
1277   textdomain (PACKAGE);
1278
1279   atexit (close_stdout);
1280
1281   global_argv = argv;
1282   controls = NULL;
1283   control_used = 0;
1284   suppress_count = false;
1285   remove_files = true;
1286   prefix = DEFAULT_PREFIX;
1287
1288   /* Change the way xmalloc and xrealloc fail.  */
1289   xalloc_fail_func = cleanup;
1290
1291 #ifdef SA_NOCLDSTOP
1292   newact.sa_handler = interrupt_handler;
1293   sigemptyset (&newact.sa_mask);
1294   newact.sa_flags = 0;
1295
1296   sigaction (SIGHUP, NULL, &oldact);
1297   if (oldact.sa_handler != SIG_IGN)
1298     sigaction (SIGHUP, &newact, NULL);
1299
1300   sigaction (SIGINT, NULL, &oldact);
1301   if (oldact.sa_handler != SIG_IGN)
1302     sigaction (SIGINT, &newact, NULL);
1303
1304   sigaction (SIGQUIT, NULL, &oldact);
1305   if (oldact.sa_handler != SIG_IGN)
1306     sigaction (SIGQUIT, &newact, NULL);
1307
1308   sigaction (SIGTERM, NULL, &oldact);
1309   if (oldact.sa_handler != SIG_IGN)
1310     sigaction (SIGTERM, &newact, NULL);
1311 #else
1312   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1313     signal (SIGHUP, interrupt_handler);
1314   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1315     signal (SIGINT, interrupt_handler);
1316   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1317     signal (SIGQUIT, interrupt_handler);
1318   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
1319     signal (SIGTERM, interrupt_handler);
1320 #endif
1321
1322   while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, NULL)) != -1)
1323     switch (optc)
1324       {
1325       case 0:
1326         break;
1327
1328       case 'f':
1329         prefix = optarg;
1330         break;
1331
1332       case 'b':
1333         suffix = optarg;
1334         break;
1335
1336       case 'k':
1337         remove_files = false;
1338         break;
1339
1340       case 'n':
1341         if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
1342             || val > INT_MAX)
1343           error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
1344         digits = (int) val;
1345         break;
1346
1347       case 's':
1348       case 'q':
1349         suppress_count = true;
1350         break;
1351
1352       case 'z':
1353         elide_empty_files = true;
1354         break;
1355
1356       case_GETOPT_HELP_CHAR;
1357
1358       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
1359
1360       default:
1361         usage (EXIT_FAILURE);
1362       }
1363
1364   if (argc - optind < 2)
1365     {
1366       error (0, 0, _("too few arguments"));
1367       usage (EXIT_FAILURE);
1368     }
1369
1370   if (suffix)
1371     filename_space = xmalloc (strlen (prefix) + max_out (suffix) + 2);
1372   else
1373     filename_space = xmalloc (strlen (prefix) + digits + 2);
1374
1375   set_input_file (argv[optind++]);
1376
1377   parse_patterns (argc, optind, argv);
1378
1379   split_file ();
1380
1381   if (close (input_desc) < 0)
1382     {
1383       error (0, errno, _("read error"));
1384       cleanup_fatal ();
1385     }
1386
1387   exit (EXIT_SUCCESS);
1388 }
1389
1390 void
1391 usage (int status)
1392 {
1393   if (status != 0)
1394     fprintf (stderr, _("Try `%s --help' for more information.\n"),
1395              program_name);
1396   else
1397     {
1398       printf (_("\
1399 Usage: %s [OPTION]... FILE PATTERN...\n\
1400 "),
1401               program_name);
1402       fputs (_("\
1403 Output pieces of FILE separated by PATTERN(s) to files `xx01', `xx02', ...,\n\
1404 and output byte counts of each piece to standard output.\n\
1405 \n\
1406 "), stdout);
1407       fputs (_("\
1408 Mandatory arguments to long options are mandatory for short options too.\n\
1409 "), stdout);
1410       fputs (_("\
1411   -b, --suffix-format=FORMAT use sprintf FORMAT instead of %02d\n\
1412   -f, --prefix=PREFIX        use PREFIX instead of `xx'\n\
1413   -k, --keep-files           do not remove output files on errors\n\
1414 "), stdout);
1415       fputs (_("\
1416   -n, --digits=DIGITS        use specified number of digits instead of 2\n\
1417   -s, --quiet, --silent      do not print counts of output file sizes\n\
1418   -z, --elide-empty-files    remove empty output files\n\
1419 "), stdout);
1420       fputs (HELP_OPTION_DESCRIPTION, stdout);
1421       fputs (VERSION_OPTION_DESCRIPTION, stdout);
1422       fputs (_("\
1423 \n\
1424 Read standard input if FILE is -.  Each PATTERN may be:\n\
1425 "), stdout);
1426       fputs (_("\
1427 \n\
1428   INTEGER            copy up to but not including specified line number\n\
1429   /REGEXP/[OFFSET]   copy up to but not including a matching line\n\
1430   %REGEXP%[OFFSET]   skip to, but not including a matching line\n\
1431   {INTEGER}          repeat the previous pattern specified number of times\n\
1432   {*}                repeat the previous pattern as many times as possible\n\
1433 \n\
1434 A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
1435 "), stdout);
1436       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1437     }
1438   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
1439 }