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