Compare getopt_long return value against -1, not EOF. Use NULL, not '(int *) 0'...
[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 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
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   if (p->offset > 0)
976     current_line = break_line;
977 }
978
979 /* Split the input file according to the control records we have built. */
980
981 static void
982 split_file (void)
983 {
984   unsigned int i, j;
985
986   for (i = 0; i < control_used; i++)
987     {
988       if (controls[i].regexpr)
989         {
990           for (j = 0; (controls[i].repeat_forever
991                        || j <= controls[i].repeat); j++)
992             process_regexp (&controls[i], j);
993         }
994       else
995         {
996           for (j = 0; (controls[i].repeat_forever
997                        || j <= controls[i].repeat); j++)
998             process_line_count (&controls[i], j);
999         }
1000     }
1001
1002   create_output_file ();
1003   dump_rest_of_file ();
1004   close_output_file ();
1005 }
1006
1007 /* Return the name of output file number NUM. */
1008
1009 static char *
1010 make_filename (unsigned int num)
1011 {
1012   strcpy (filename_space, prefix);
1013   if (suffix)
1014     sprintf (filename_space+strlen(prefix), suffix, num);
1015   else
1016     sprintf (filename_space+strlen(prefix), "%0*d", digits, num);
1017   return filename_space;
1018 }
1019
1020 /* Create the next output file. */
1021
1022 static void
1023 create_output_file (void)
1024 {
1025   output_filename = make_filename (files_created);
1026   output_stream = fopen (output_filename, "w");
1027   if (output_stream == NULL)
1028     {
1029       error (0, errno, "%s", output_filename);
1030       cleanup_fatal ();
1031     }
1032   files_created++;
1033   bytes_written = 0;
1034 }
1035
1036 /* Delete all the files we have created. */
1037
1038 static void
1039 delete_all_files (void)
1040 {
1041   unsigned int i;
1042   char *name;
1043
1044   for (i = 0; i < files_created; i++)
1045     {
1046       name = make_filename (i);
1047       if (unlink (name))
1048         error (0, errno, "%s", name);
1049     }
1050 }
1051
1052 /* Close the current output file and print the count
1053    of characters in this file. */
1054
1055 static void
1056 close_output_file (void)
1057 {
1058   if (output_stream)
1059     {
1060       if (fclose (output_stream) == EOF)
1061         {
1062           error (0, errno, _("write error for `%s'"), output_filename);
1063           output_stream = NULL;
1064           cleanup_fatal ();
1065         }
1066       if (bytes_written == 0 && elide_empty_files)
1067         {
1068           if (unlink (output_filename))
1069             error (0, errno, "%s", output_filename);
1070           files_created--;
1071         }
1072       else
1073         if (!suppress_count)
1074           fprintf (stdout, "%d\n", bytes_written);
1075       output_stream = NULL;
1076     }
1077 }
1078
1079 /* Save line LINE to the output file and
1080    increment the character count for the current file. */
1081
1082 static void
1083 save_line_to_file (const struct cstring *line)
1084 {
1085   fwrite (line->str, sizeof (char), line->len, output_stream);
1086   bytes_written += line->len;
1087 }
1088
1089 /* Return a new, initialized control record. */
1090
1091 static struct control *
1092 new_control_record (void)
1093 {
1094   static unsigned control_allocated = 0; /* Total space allocated. */
1095   struct control *p;
1096
1097   if (control_allocated == 0)
1098     {
1099       control_allocated = ALLOC_SIZE;
1100       controls = (struct control *)
1101         xmalloc (sizeof (struct control) * control_allocated);
1102     }
1103   else if (control_used == control_allocated)
1104     {
1105       control_allocated += ALLOC_SIZE;
1106       controls = (struct control *)
1107         xrealloc ((char *) controls,
1108                   sizeof (struct control) * control_allocated);
1109     }
1110   p = &controls[control_used++];
1111   p->regexpr = NULL;
1112   p->repeat = 0;
1113   p->repeat_forever = 0;
1114   p->lines_required = 0;
1115   p->offset = 0;
1116   return p;
1117 }
1118
1119 /* Check if there is a numeric offset after a regular expression.
1120    STR is the entire command line argument.
1121    P is the control record for this regular expression.
1122    NUM is the numeric part of STR. */
1123
1124 static void
1125 check_for_offset (struct control *p, const char *str, const char *num)
1126 {
1127   unsigned long val;
1128
1129   if (*num != '-' && *num != '+')
1130     error (EXIT_FAILURE, 0, _("%s: `+' or `-' expected after delimeter"), str);
1131
1132   if (xstrtoul (num + 1, NULL, 10, &val, "") != LONGINT_OK
1133       || val > UINT_MAX)
1134     error (EXIT_FAILURE, 0, _("%s: integer expected after `%c'"), str, *num);
1135   p->offset = (unsigned int) val;
1136
1137   if (*num == '-')
1138     p->offset = -p->offset;
1139 }
1140
1141 /* Given that the first character of command line arg STR is '{',
1142    make sure that the rest of the string is a valid repeat count
1143    and store its value in P.
1144    ARGNUM is the ARGV index of STR. */
1145
1146 static void
1147 parse_repeat_count (int argnum, struct control *p, char *str)
1148 {
1149   unsigned long val;
1150   char *end;
1151
1152   end = str + strlen (str) - 1;
1153   if (*end != '}')
1154     error (EXIT_FAILURE, 0, _("%s: `}' is required in repeat count"), str);
1155   *end = '\0';
1156
1157   if (str+1 == end-1 && *(str+1) == '*')
1158     p->repeat_forever = 1;
1159   else
1160     {
1161       if (xstrtoul (str + 1, NULL, 10, &val, "") != LONGINT_OK
1162           || val > UINT_MAX)
1163         {
1164           error (EXIT_FAILURE, 0,
1165                  _("%s}: integer required between `{' and `}'"),
1166                  global_argv[argnum]);
1167         }
1168       p->repeat = (unsigned int) val;
1169     }
1170
1171   *end = '}';
1172 }
1173
1174 /* Extract the regular expression from STR and check for a numeric offset.
1175    STR should start with the regexp delimiter character.
1176    Return a new control record for the regular expression.
1177    ARGNUM is the ARGV index of STR.
1178    Unless IGNORE is TRUE, mark these lines for output. */
1179
1180 static struct control *
1181 extract_regexp (int argnum, boolean ignore, char *str)
1182 {
1183   int len;                      /* Number of chars in this regexp. */
1184   char delim = *str;
1185   char *closing_delim;
1186   struct control *p;
1187   const char *err;
1188
1189   closing_delim = strrchr (str + 1, delim);
1190   if (closing_delim == NULL)
1191     error (EXIT_FAILURE, 0,
1192            _("%s: closing delimeter `%c' missing"), str, delim);
1193
1194   len = closing_delim - str - 1;
1195   p = new_control_record ();
1196   p->argnum = argnum;
1197   p->ignore = ignore;
1198
1199   p->regexpr = (char *) xmalloc ((unsigned) (len + 1));
1200   strncpy (p->regexpr, str + 1, len);
1201   p->re_compiled.allocated = len * 2;
1202   p->re_compiled.buffer = (unsigned char *) xmalloc (p->re_compiled.allocated);
1203   p->re_compiled.fastmap = xmalloc (256);
1204   p->re_compiled.translate = 0;
1205 #if !WITH_REGEX
1206   p->re_compiled.syntax_parens = 0;
1207 #endif
1208   err = re_compile_pattern (p->regexpr, len, &p->re_compiled);
1209   if (err)
1210     {
1211       error (0, 0, _("%s: invalid regular expression: %s"), str, err);
1212       cleanup_fatal ();
1213     }
1214
1215   if (closing_delim[1])
1216     check_for_offset (p, str, closing_delim + 1);
1217
1218   return p;
1219 }
1220
1221 /* Extract the break patterns from args START through ARGC - 1 of ARGV.
1222    After each pattern, check if the next argument is a repeat count. */
1223
1224 static void
1225 parse_patterns (int argc, int start, char **argv)
1226 {
1227   int i;                        /* Index into ARGV. */
1228   struct control *p;            /* New control record created. */
1229   unsigned long val;
1230   static unsigned long last_val = 0;
1231
1232   for (i = start; i < argc; i++)
1233     {
1234       if (*argv[i] == '/' || *argv[i] == '%')
1235         {
1236           p = extract_regexp (i, *argv[i] == '%', argv[i]);
1237         }
1238       else
1239         {
1240           p = new_control_record ();
1241           p->argnum = i;
1242
1243           if (xstrtoul (argv[i], NULL, 10, &val, "") != LONGINT_OK
1244               || val > INT_MAX)
1245             error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
1246           if (val == 0)
1247             error (EXIT_FAILURE, 0,
1248                    _("%s: line number must be greater than zero"),
1249                    argv[i]);
1250           if (val < last_val)
1251             error (EXIT_FAILURE, 0,
1252              _("line number `%s' is smaller than preceding line number, %lu"),
1253                    argv[i], last_val);
1254
1255           if (val == last_val)
1256             error (0, 0,
1257            _("warning: line number `%s' is the same as preceding line number"),
1258                    argv[i]);
1259           last_val = val;
1260
1261           p->lines_required = (int) val;
1262         }
1263
1264       if (i + 1 < argc && *argv[i + 1] == '{')
1265         {
1266           /* We have a repeat count. */
1267           i++;
1268           parse_repeat_count (i, p, argv[i]);
1269         }
1270     }
1271 }
1272
1273 static unsigned
1274 get_format_flags (char **format_ptr)
1275 {
1276   unsigned count = 0;
1277
1278   for (; **format_ptr; (*format_ptr)++)
1279     {
1280       switch (**format_ptr)
1281         {
1282         case '-':
1283           break;
1284
1285         case '+':
1286         case ' ':
1287           count++;
1288           break;
1289
1290         case '#':
1291           count += 2;   /* Allow for 0x prefix preceeding an `x' conversion.  */
1292           break;
1293
1294         default:
1295           return count;
1296         }
1297     }
1298   return count;
1299 }
1300
1301 static unsigned
1302 get_format_width (char **format_ptr)
1303 {
1304   unsigned count = 0;
1305   char *start;
1306   int ch_save;
1307
1308   start = *format_ptr;
1309   for (; ISDIGIT (**format_ptr); (*format_ptr)++)
1310     continue;
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 (; ISDIGIT (**format_ptr); (*format_ptr)++)
1347     continue;
1348
1349   /* ANSI 4.9.6.1 says that if the precision is negative, it's as good as
1350      not there. */
1351   if (is_negative)
1352     start = *format_ptr;
1353
1354   ch_save = **format_ptr;
1355   **format_ptr = '\0';
1356   count = (*format_ptr == start) ? 11 : atoi (start);
1357   **format_ptr = ch_save;
1358
1359   return count;
1360 }
1361
1362 static void
1363 get_format_conv_type (char **format_ptr)
1364 {
1365   int ch = *((*format_ptr)++);
1366
1367   switch (ch)
1368     {
1369     case 'd':
1370     case 'i':
1371     case 'o':
1372     case 'u':
1373     case 'x':
1374     case 'X':
1375       break;
1376
1377     case 0:
1378       error (EXIT_FAILURE, 0, _("missing conversion specifier in suffix"));
1379       break;
1380
1381     default:
1382       if (ISPRINT (ch))
1383         error (EXIT_FAILURE, 0,
1384                _("invalid conversion specifier in suffix: %c"), ch);
1385       else
1386         error (EXIT_FAILURE, 0,
1387                _("invalid conversion specifier in suffix: \\%.3o"), ch);
1388     }
1389 }
1390
1391 static unsigned
1392 max_out (char *format)
1393 {
1394   unsigned out_count = 0;
1395   unsigned percents = 0;
1396
1397   for (; *format; )
1398     {
1399       int ch = *format++;
1400
1401       if (ch != '%')
1402         out_count++;
1403       else
1404         {
1405           percents++;
1406           out_count += get_format_flags (&format);
1407           {
1408             int width = get_format_width (&format);
1409             int prec = get_format_prec (&format);
1410
1411             out_count += MAX (width, prec);
1412           }
1413           get_format_conv_type (&format);
1414         }
1415     }
1416
1417   if (percents == 0)
1418     error (EXIT_FAILURE, 0,
1419            _("missing %% conversion specification in suffix"));
1420   else if (percents > 1)
1421     error (EXIT_FAILURE, 0,
1422            _("too many %% conversion specifications in suffix"));
1423
1424   return out_count;
1425 }
1426
1427 int
1428 main (int argc, char **argv)
1429 {
1430   int optc;
1431   unsigned long val;
1432 #ifdef SA_INTERRUPT
1433   struct sigaction oldact, newact;
1434 #endif
1435
1436   program_name = argv[0];
1437   setlocale (LC_ALL, "");
1438   bindtextdomain (PACKAGE, LOCALEDIR);
1439   textdomain (PACKAGE);
1440
1441   global_argv = argv;
1442   controls = NULL;
1443   control_used = 0;
1444   suppress_count = FALSE;
1445   remove_files = TRUE;
1446   prefix = DEFAULT_PREFIX;
1447
1448 #ifdef SA_INTERRUPT
1449   newact.sa_handler = interrupt_handler;
1450   sigemptyset (&newact.sa_mask);
1451   newact.sa_flags = 0;
1452
1453   sigaction (SIGHUP, NULL, &oldact);
1454   if (oldact.sa_handler != SIG_IGN)
1455     sigaction (SIGHUP, &newact, NULL);
1456
1457   sigaction (SIGINT, NULL, &oldact);
1458   if (oldact.sa_handler != SIG_IGN)
1459     sigaction (SIGINT, &newact, NULL);
1460
1461   sigaction (SIGQUIT, NULL, &oldact);
1462   if (oldact.sa_handler != SIG_IGN)
1463     sigaction (SIGQUIT, &newact, NULL);
1464
1465   sigaction (SIGTERM, NULL, &oldact);
1466   if (oldact.sa_handler != SIG_IGN)
1467     sigaction (SIGTERM, &newact, NULL);
1468 #else /* not SA_INTERRUPT */
1469   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1470     signal (SIGHUP, interrupt_handler);
1471   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1472     signal (SIGINT, interrupt_handler);
1473   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1474     signal (SIGQUIT, interrupt_handler);
1475   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
1476     signal (SIGTERM, interrupt_handler);
1477 #endif /* not SA_INTERRUPT */
1478
1479   while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, NULL)) != -1)
1480     switch (optc)
1481       {
1482       case 0:
1483         break;
1484
1485       case 'f':
1486         prefix = optarg;
1487         break;
1488
1489       case 'b':
1490         suffix = optarg;
1491         break;
1492
1493       case 'k':
1494         remove_files = FALSE;
1495         break;
1496
1497       case 'n':
1498         if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
1499             || val > INT_MAX)
1500           error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
1501         digits = (int) val;
1502         break;
1503
1504       case 's':
1505       case 'q':
1506         suppress_count = TRUE;
1507         break;
1508
1509       case 'z':
1510         elide_empty_files = TRUE;
1511         break;
1512
1513       default:
1514         usage (1);
1515       }
1516
1517   if (show_version)
1518     {
1519       printf ("csplit (%s) %s\n", GNU_PACKAGE, VERSION);
1520       exit (EXIT_SUCCESS);
1521     }
1522
1523   if (show_help)
1524     usage (0);
1525
1526   if (argc - optind < 2)
1527     {
1528       error (0, 0, _("too few arguments"));
1529       usage (1);
1530     }
1531
1532   if (suffix)
1533     filename_space = (char *) xmalloc (strlen (prefix) + max_out (suffix) + 2);
1534   else
1535     filename_space = (char *) xmalloc (strlen (prefix) + digits + 2);
1536
1537   set_input_file (argv[optind++]);
1538
1539   parse_patterns (argc, optind, argv);
1540
1541   split_file ();
1542
1543   if (close (input_desc) < 0)
1544     {
1545       error (0, errno, _("read error"));
1546       cleanup_fatal ();
1547     }
1548
1549   exit (EXIT_SUCCESS);
1550 }
1551
1552 static void
1553 usage (int status)
1554 {
1555   if (status != 0)
1556     fprintf (stderr, _("Try `%s --help' for more information.\n"),
1557              program_name);
1558   else
1559     {
1560       printf (_("\
1561 Usage: %s [OPTION]... FILE PATTERN...\n\
1562 "),
1563               program_name);
1564       printf (_("\
1565 Output pieces of FILE separated by PATTERN(s) to files `xx01', `xx02', ...,\n\
1566 and output byte counts of each piece to standard output.\n\
1567 \n\
1568   -b, --suffix-format=FORMAT use sprintf FORMAT instead of %%d\n\
1569   -f, --prefix=PREFIX        use PREFIX instead of `xx'\n\
1570   -k, --keep-files           do not remove output files on errors\n\
1571   -n, --digits=DIGITS        use specified number of digits instead of 2\n\
1572   -s, --quiet, --silent      do not print counts of output file sizes\n\
1573   -z, --elide-empty-files    remove empty output files\n\
1574       --help                 display this help and exit\n\
1575       --version              output version information and exit\n\
1576 \n\
1577 Read standard input if FILE is -.  Each PATTERN may be:\n\
1578 \n\
1579   INTEGER            copy up to but not including specified line number\n\
1580   /REGEXP/[OFFSET]   copy up to but not including a matching line\n\
1581   %%REGEXP%%[OFFSET]   skip to, but not including a matching line\n\
1582   {INTEGER}          repeat the previous pattern specified number of times\n\
1583   {*}                repeat the previous pattern as many times as possible\n\
1584 \n\
1585 A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
1586 "));
1587       puts (_("\nReport bugs to textutils-bugs@gnu.ai.mit.edu"));
1588     }
1589   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
1590 }