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