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