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