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