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