1 /* csplit - split a file into sections determined by context lines
2 Copyright (C) 91, 1995-2004 Free Software Foundation, Inc.
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)
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.
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. */
18 /* Written by Stuart Kemp, cpsrk@groper.jcu.edu.au.
19 Modified by David MacKenzie, djm@gnu.ai.mit.edu. */
25 #include <sys/types.h>
34 #include "safe-read.h"
38 # define sigprocmask(How, Set, Oset) /* empty */
42 /* The official name of this program (e.g., no `g' prefix). */
43 #define PROGRAM_NAME "csplit"
45 #define AUTHORS "Stuart Kemp", "David MacKenzie"
47 /* Increment size of area for control records. */
50 /* The default prefix for output file names. */
51 #define DEFAULT_PREFIX "xx"
53 /* A compiled pattern arg. */
56 char *regexpr; /* Non-compiled regular expression. */
57 struct re_pattern_buffer re_compiled; /* Compiled regular expression. */
58 intmax_t offset; /* Offset from regexp to split at. */
59 uintmax_t lines_required; /* Number of lines required. */
60 uintmax_t repeat; /* Repeat count. */
61 int argnum; /* ARGV index. */
62 bool repeat_forever; /* True if `*' used as a repeat count. */
63 bool ignore; /* If true, produce no output (for regexp). */
66 /* Initial size of data area in buffers. */
67 #define START_SIZE 8191
69 /* Increment size for data area. */
70 #define INCR_SIZE 2048
72 /* Number of lines kept in each node in line list. */
76 /* Some small values to test the algorithms. */
77 # define START_SIZE 200
82 /* A string with a length count. */
89 /* Pointers to the beginnings of lines in the buffer area.
90 These structures are linked together if needed. */
93 unsigned int used; /* Number of offsets used in this struct. */
94 unsigned int insert_index; /* Next offset to use when inserting line. */
95 unsigned int retrieve_index; /* Next index to use when retrieving line. */
96 struct cstring starts[CTRL_SIZE]; /* Lines in the data area. */
97 struct line *next; /* Next in linked list. */
100 /* The structure to hold the input lines.
101 Contains a pointer to the data area and a list containing
102 pointers to the individual lines. */
105 size_t bytes_alloc; /* Size of the buffer area. */
106 size_t bytes_used; /* Bytes used in the buffer area. */
107 uintmax_t start_line; /* First line number in this buffer. */
108 uintmax_t first_available; /* First line that can be retrieved. */
109 size_t num_lines; /* Number of complete lines in this buffer. */
110 char *buffer; /* Data area. */
111 struct line *line_start; /* Head of list of pointers to lines. */
112 struct line *curr_line; /* The line start record currently in use. */
113 struct buffer_record *next;
116 static void close_output_file (void);
117 static void create_output_file (void);
118 static void delete_all_files (void);
119 static void save_line_to_file (const struct cstring *line);
120 void usage (int status);
122 /* The name this program was run with. */
125 /* Input file descriptor. */
126 static int input_desc = 0;
128 /* Start of buffer list. */
129 static struct buffer_record *head = NULL;
131 /* Partially read line. */
132 static char *hold_area = NULL;
134 /* Number of bytes in `hold_area'. */
135 static size_t hold_count = 0;
137 /* Number of the last line in the buffers. */
138 static uintmax_t last_line_number = 0;
140 /* Number of the line currently being examined. */
141 static uintmax_t current_line = 0;
143 /* If true, we have read EOF. */
144 static bool have_read_eof = false;
146 /* Name of output files. */
147 static char * volatile filename_space = NULL;
149 /* Prefix part of output file names. */
150 static char * volatile prefix = NULL;
152 /* Suffix part of output file names. */
153 static char * volatile suffix = NULL;
155 /* Number of digits to use in output file names. */
156 static int volatile digits = 2;
158 /* Number of files created so far. */
159 static unsigned int volatile files_created = 0;
161 /* Number of bytes written to current file. */
162 static uintmax_t bytes_written;
164 /* Output file pointer. */
165 static FILE *output_stream = NULL;
167 /* Output file name. */
168 static char *output_filename = NULL;
170 /* Perhaps it would be cleaner to pass arg values instead of indexes. */
171 static char **global_argv;
173 /* If true, do not print the count of bytes in each output file. */
174 static bool suppress_count;
176 /* If true, remove output files on error. */
177 static bool volatile remove_files;
179 /* If true, remove all output files which have a zero length. */
180 static bool elide_empty_files;
182 /* The compiled pattern arguments, which determine how to split
184 static struct control *controls;
186 /* Number of elements in `controls'. */
187 static size_t control_used;
189 /* The set of signals that are caught. */
190 static sigset_t caught_signals;
192 static struct option const longopts[] =
194 {"digits", required_argument, NULL, 'n'},
195 {"quiet", no_argument, NULL, 'q'},
196 {"silent", no_argument, NULL, 's'},
197 {"keep-files", no_argument, NULL, 'k'},
198 {"elide-empty-files", no_argument, NULL, 'z'},
199 {"prefix", required_argument, NULL, 'f'},
200 {"suffix-format", required_argument, NULL, 'b'},
201 {GETOPT_HELP_OPTION_DECL},
202 {GETOPT_VERSION_OPTION_DECL},
206 /* Optionally remove files created so far; then exit.
207 Called when an error detected. */
214 close_output_file ();
216 sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
218 sigprocmask (SIG_SETMASK, &oldset, NULL);
221 static void cleanup_fatal (void) ATTRIBUTE_NORETURN;
230 interrupt_handler (int sig)
233 signal (sig, SIG_IGN);
238 signal (sig, SIG_DFL);
242 /* Keep track of NUM bytes of a partial line in buffer START.
243 These bytes will be retrieved later when another large buffer is read.
244 It is not necessary to create a new buffer for these bytes; instead,
245 we keep a pointer to the existing buffer. This buffer *is* on the
246 free list, and when the next buffer is obtained from this list
247 (even if it is this one), these bytes will be placed at the
248 start of the new buffer. */
251 save_to_hold_area (char *start, size_t num)
257 /* Read up to MAX_N_BYTES bytes from the input stream into DEST.
258 Return the number of bytes read. */
261 read_input (char *dest, size_t max_n_bytes)
265 if (max_n_bytes == 0)
268 bytes_read = safe_read (input_desc, dest, max_n_bytes);
271 have_read_eof = true;
273 if (bytes_read == SAFE_READ_ERROR)
275 error (0, errno, _("read error"));
282 /* Initialize existing line record P. */
285 clear_line_control (struct line *p)
289 p->retrieve_index = 0;
292 /* Return a new, initialized line record. */
295 new_line_control (void)
297 struct line *p = xmalloc (sizeof *p);
300 clear_line_control (p);
305 /* Record LINE_START, which is the address of the start of a line
306 of length LINE_LEN in the large buffer, in the lines buffer of B. */
309 keep_new_line (struct buffer_record *b, char *line_start, size_t line_len)
313 /* If there is no existing area to keep line info, get some. */
314 if (b->line_start == NULL)
315 b->line_start = b->curr_line = new_line_control ();
317 /* If existing area for lines is full, get more. */
318 if (b->curr_line->used == CTRL_SIZE)
320 b->curr_line->next = new_line_control ();
321 b->curr_line = b->curr_line->next;
326 /* Record the start of the line, and update counters. */
327 l->starts[l->insert_index].str = line_start;
328 l->starts[l->insert_index].len = line_len;
333 /* Scan the buffer in B for newline characters
334 and record the line start locations and lengths in B.
335 Return the number of lines found in this buffer.
337 There may be an incomplete line at the end of the buffer;
338 a pointer is kept to this area, which will be used when
339 the next buffer is filled. */
342 record_line_starts (struct buffer_record *b)
344 char *line_start; /* Start of current line. */
345 char *line_end; /* End of each line found. */
346 size_t bytes_left; /* Length of incomplete last line. */
347 size_t lines; /* Number of lines found. */
348 size_t line_length; /* Length of each line found. */
350 if (b->bytes_used == 0)
354 line_start = b->buffer;
355 bytes_left = b->bytes_used;
359 line_end = memchr (line_start, '\n', bytes_left);
360 if (line_end == NULL)
362 line_length = line_end - line_start + 1;
363 keep_new_line (b, line_start, line_length);
364 bytes_left -= line_length;
365 line_start = line_end + 1;
369 /* Check for an incomplete last line. */
374 keep_new_line (b, line_start, bytes_left);
378 save_to_hold_area (line_start, bytes_left);
381 b->num_lines = lines;
382 b->first_available = b->start_line = last_line_number + 1;
383 last_line_number += lines;
388 /* Return a new buffer with room to store SIZE bytes, plus
389 an extra byte for safety. */
391 static struct buffer_record *
392 create_new_buffer (size_t size)
394 struct buffer_record *new_buffer = xmalloc (sizeof *new_buffer);
396 new_buffer->buffer = xmalloc (size + 1);
398 new_buffer->bytes_alloc = size;
399 new_buffer->line_start = new_buffer->curr_line = NULL;
404 /* Return a new buffer of at least MINSIZE bytes. If a buffer of at
405 least that size is currently free, use it, otherwise create a new one. */
407 static struct buffer_record *
408 get_new_buffer (size_t min_size)
410 struct buffer_record *new_buffer; /* Buffer to return. */
411 size_t alloc_size; /* Actual size that will be requested. */
413 alloc_size = START_SIZE;
414 if (alloc_size < min_size)
416 size_t s = min_size - alloc_size + INCR_SIZE - 1;
417 alloc_size += s - s % INCR_SIZE;
420 new_buffer = create_new_buffer (alloc_size);
422 new_buffer->num_lines = 0;
423 new_buffer->bytes_used = 0;
424 new_buffer->start_line = new_buffer->first_available = last_line_number + 1;
425 new_buffer->next = NULL;
431 free_buffer (struct buffer_record *buf)
436 /* Append buffer BUF to the linked list of buffers that contain
437 some data yet to be processed. */
440 save_buffer (struct buffer_record *buf)
442 struct buffer_record *p;
445 buf->curr_line = buf->line_start;
451 for (p = head; p->next; p = p->next)
457 /* Fill a buffer of input.
459 Set the initial size of the buffer to a default.
460 Fill the buffer (from the hold area and input stream)
461 and find the individual lines.
462 If no lines are found (the buffer is too small to hold the next line),
463 release the current buffer (whose contents would have been put in the
464 hold area) and repeat the process with another large buffer until at least
465 one entire line has been read.
467 Return true if a new buffer was obtained, otherwise false
468 (in which case end-of-file must have been encountered). */
473 struct buffer_record *b;
474 size_t bytes_wanted = START_SIZE; /* Minimum buffer size. */
475 size_t bytes_avail; /* Size of new buffer created. */
476 size_t lines_found; /* Number of lines in this new buffer. */
477 char *p; /* Place to load into buffer. */
482 /* We must make the buffer at least as large as the amount of data
483 in the partial line left over from the last call. */
484 if (bytes_wanted < hold_count)
485 bytes_wanted = hold_count;
489 b = get_new_buffer (bytes_wanted);
490 bytes_avail = b->bytes_alloc; /* Size of buffer returned. */
493 /* First check the `holding' area for a partial line. */
497 memcpy (p, hold_area, hold_count);
499 b->bytes_used += hold_count;
500 bytes_avail -= hold_count;
504 b->bytes_used += read_input (p, bytes_avail);
506 lines_found = record_line_starts (b);
507 bytes_wanted = b->bytes_alloc * 2;
511 while (!lines_found && !have_read_eof);
516 return lines_found != 0;
519 /* Return the line number of the first line that has not yet been retrieved. */
522 get_first_line_in_buffer (void)
524 if (head == NULL && !load_buffer ())
525 error (EXIT_FAILURE, errno, _("input disappeared"));
527 return head->first_available;
530 /* Return a pointer to the logical first line in the buffer and make the
531 next line the logical first line.
532 Return NULL if there is no more input. */
534 static struct cstring *
537 /* If non-NULL, this is the buffer for which the previous call
538 returned the final line. So now, presuming that line has been
539 processed, we can free the buffer and reset this pointer. */
540 static struct buffer_record *prev_buf = NULL;
542 struct cstring *line; /* Return value. */
543 struct line *l; /* For convenience. */
547 free_buffer (prev_buf);
551 if (head == NULL && !load_buffer ())
554 if (current_line < head->first_available)
555 current_line = head->first_available;
557 ++(head->first_available);
561 line = &l->starts[l->retrieve_index];
563 /* Advance index to next line. */
564 if (++l->retrieve_index == l->used)
566 /* Go on to the next line record. */
567 head->curr_line = l->next;
568 if (head->curr_line == NULL || head->curr_line->used == 0)
570 /* Go on to the next data block.
571 but first record the current one so we can free it
572 once the line we're returning has been processed. */
581 /* Search the buffers for line LINENUM, reading more input if necessary.
582 Return a pointer to the line, or NULL if it is not found in the file. */
584 static struct cstring *
585 find_line (uintmax_t linenum)
587 struct buffer_record *b;
589 if (head == NULL && !load_buffer ())
592 if (linenum < head->start_line)
597 if (linenum < b->start_line + b->num_lines)
599 /* The line is in this buffer. */
601 size_t offset; /* How far into the buffer the line is. */
604 offset = linenum - b->start_line;
605 /* Find the control record. */
606 while (offset >= CTRL_SIZE)
611 return &l->starts[offset];
613 if (b->next == NULL && !load_buffer ())
615 b = b->next; /* Try the next data block. */
619 /* Return true if at least one more line is available for input. */
624 return find_line (current_line + 1) == NULL;
627 /* Set the name of the input file to NAME and open it. */
630 set_input_file (const char *name)
632 if (STREQ (name, "-"))
636 input_desc = open (name, O_RDONLY);
638 error (EXIT_FAILURE, errno, "%s", name);
642 /* Write all lines from the beginning of the buffer up to, but
643 not including, line LAST_LINE, to the current output file.
644 If IGNORE is true, do not output lines selected here.
645 ARGNUM is the index in ARGV of the current pattern. */
648 write_to_file (uintmax_t last_line, bool ignore, int argnum)
650 struct cstring *line;
651 uintmax_t first_line; /* First available input line. */
652 uintmax_t lines; /* Number of lines to output. */
655 first_line = get_first_line_in_buffer ();
657 if (first_line > last_line)
659 error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
663 lines = last_line - first_line;
665 for (i = 0; i < lines; i++)
667 line = remove_line ();
670 error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
674 save_line_to_file (line);
678 /* Output any lines left after all regexps have been processed. */
681 dump_rest_of_file (void)
683 struct cstring *line;
685 while ((line = remove_line ()) != NULL)
686 save_line_to_file (line);
689 /* Handle an attempt to read beyond EOF under the control of record P,
690 on iteration REPETITION if nonzero. */
692 static void handle_line_error (const struct control *, uintmax_t)
695 handle_line_error (const struct control *p, uintmax_t repetition)
697 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
699 fprintf (stderr, _("%s: `%s': line number out of range"),
700 program_name, umaxtostr (p->lines_required, buf));
702 fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
704 fprintf (stderr, "\n");
709 /* Determine the line number that marks the end of this file,
710 then get those lines and save them to the output file.
711 P is the control record.
712 REPETITION is the repetition number. */
715 process_line_count (const struct control *p, uintmax_t repetition)
718 uintmax_t last_line_to_save = p->lines_required * (repetition + 1);
719 struct cstring *line;
721 create_output_file ();
723 linenum = get_first_line_in_buffer ();
725 while (linenum++ < last_line_to_save)
727 line = remove_line ();
729 handle_line_error (p, repetition);
730 save_line_to_file (line);
733 close_output_file ();
735 /* Ensure that the line number specified is not 1 greater than
736 the number of lines in the file. */
737 if (no_more_lines ())
738 handle_line_error (p, repetition);
741 static void regexp_error (struct control *, uintmax_t, bool) ATTRIBUTE_NORETURN;
743 regexp_error (struct control *p, uintmax_t repetition, bool ignore)
745 fprintf (stderr, _("%s: `%s': match not found"),
746 program_name, global_argv[p->argnum]);
750 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
751 fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
754 fprintf (stderr, "\n");
758 dump_rest_of_file ();
759 close_output_file ();
764 /* Read the input until a line matches the regexp in P, outputting
765 it unless P->IGNORE is true.
766 REPETITION is this repeat-count; 0 means the first time. */
769 process_regexp (struct control *p, uintmax_t repetition)
771 struct cstring *line; /* From input file. */
772 size_t line_len; /* To make "$" in regexps work. */
773 uintmax_t break_line; /* First line number of next file. */
774 bool ignore = p->ignore; /* If true, skip this section. */
778 create_output_file ();
780 /* If there is no offset for the regular expression, or
781 it is positive, then it is not necessary to buffer the lines. */
787 line = find_line (++current_line);
790 if (p->repeat_forever)
794 dump_rest_of_file ();
795 close_output_file ();
800 regexp_error (p, repetition, ignore);
802 line_len = line->len;
803 if (line->str[line_len - 1] == '\n')
805 ret = re_search (&p->re_compiled, line->str, line_len,
809 error (0, 0, _("error in regular expression search"));
814 line = remove_line ();
816 save_line_to_file (line);
824 /* Buffer the lines. */
827 line = find_line (++current_line);
830 if (p->repeat_forever)
834 dump_rest_of_file ();
835 close_output_file ();
840 regexp_error (p, repetition, ignore);
842 line_len = line->len;
843 if (line->str[line_len - 1] == '\n')
845 ret = re_search (&p->re_compiled, line->str, line_len,
849 error (0, 0, _("error in regular expression search"));
857 /* Account for any offset from this regexp. */
858 break_line = current_line + p->offset;
860 write_to_file (break_line, ignore, p->argnum);
863 close_output_file ();
866 current_line = break_line;
869 /* Split the input file according to the control records we have built. */
876 for (i = 0; i < control_used; i++)
879 if (controls[i].regexpr)
881 for (j = 0; (controls[i].repeat_forever
882 || j <= controls[i].repeat); j++)
883 process_regexp (&controls[i], j);
887 for (j = 0; (controls[i].repeat_forever
888 || j <= controls[i].repeat); j++)
889 process_line_count (&controls[i], j);
893 create_output_file ();
894 dump_rest_of_file ();
895 close_output_file ();
898 /* Return the name of output file number NUM. */
901 make_filename (unsigned int num)
903 strcpy (filename_space, prefix);
905 sprintf (filename_space+strlen(prefix), suffix, num);
907 sprintf (filename_space+strlen(prefix), "%0*u", digits, num);
908 return filename_space;
911 /* Create the next output file. */
914 create_output_file (void)
920 output_filename = make_filename (files_created);
922 /* Create the output file in a critical section, to avoid races. */
923 sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
924 output_stream = fopen (output_filename, "w");
925 fopen_ok = (output_stream != NULL);
927 files_created += fopen_ok;
928 sigprocmask (SIG_SETMASK, &oldset, NULL);
932 error (0, fopen_errno, "%s", output_filename);
938 /* If requested, delete all the files we have created. This function
939 must be called only from critical sections. */
942 delete_all_files (void)
949 for (i = 0; i < files_created; i++)
951 const char *name = make_filename (i);
953 error (0, errno, "%s", name);
959 /* Close the current output file and print the count
960 of characters in this file. */
963 close_output_file (void)
967 if (ferror (output_stream))
969 error (0, 0, _("write error for `%s'"), output_filename);
970 output_stream = NULL;
973 if (fclose (output_stream) != 0)
975 error (0, errno, "%s", output_filename);
976 output_stream = NULL;
979 if (bytes_written == 0 && elide_empty_files)
985 /* Remove the output file in a critical section, to avoid races. */
986 sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
987 unlink_ok = (unlink (output_filename) == 0);
988 unlink_errno = errno;
989 files_created -= unlink_ok;
990 sigprocmask (SIG_SETMASK, &oldset, NULL);
993 error (0, unlink_errno, "%s", output_filename);
999 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
1000 fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
1003 output_stream = NULL;
1007 /* Save line LINE to the output file and
1008 increment the character count for the current file. */
1011 save_line_to_file (const struct cstring *line)
1013 fwrite (line->str, sizeof (char), line->len, output_stream);
1014 bytes_written += line->len;
1017 /* Return a new, initialized control record. */
1019 static struct control *
1020 new_control_record (void)
1022 static size_t control_allocated = 0; /* Total space allocated. */
1025 if (control_used == control_allocated)
1026 controls = x2nrealloc (controls, &control_allocated, sizeof *controls);
1027 p = &controls[control_used++];
1030 p->repeat_forever = false;
1031 p->lines_required = 0;
1036 /* Check if there is a numeric offset after a regular expression.
1037 STR is the entire command line argument.
1038 P is the control record for this regular expression.
1039 NUM is the numeric part of STR. */
1042 check_for_offset (struct control *p, const char *str, const char *num)
1044 if (xstrtoimax (num, NULL, 10, &p->offset, "") != LONGINT_OK)
1045 error (EXIT_FAILURE, 0, _("%s: integer expected after delimiter"), str);
1048 /* Given that the first character of command line arg STR is '{',
1049 make sure that the rest of the string is a valid repeat count
1050 and store its value in P.
1051 ARGNUM is the ARGV index of STR. */
1054 parse_repeat_count (int argnum, struct control *p, char *str)
1059 end = str + strlen (str) - 1;
1061 error (EXIT_FAILURE, 0, _("%s: `}' is required in repeat count"), str);
1064 if (str+1 == end-1 && *(str+1) == '*')
1065 p->repeat_forever = true;
1068 if (xstrtoumax (str + 1, NULL, 10, &val, "") != LONGINT_OK)
1070 error (EXIT_FAILURE, 0,
1071 _("%s}: integer required between `{' and `}'"),
1072 global_argv[argnum]);
1080 /* Extract the regular expression from STR and check for a numeric offset.
1081 STR should start with the regexp delimiter character.
1082 Return a new control record for the regular expression.
1083 ARGNUM is the ARGV index of STR.
1084 Unless IGNORE is true, mark these lines for output. */
1086 static struct control *
1087 extract_regexp (int argnum, bool ignore, char *str)
1089 size_t len; /* Number of bytes in this regexp. */
1091 char *closing_delim;
1095 closing_delim = strrchr (str + 1, delim);
1096 if (closing_delim == NULL)
1097 error (EXIT_FAILURE, 0,
1098 _("%s: closing delimiter `%c' missing"), str, delim);
1100 len = closing_delim - str - 1;
1101 p = new_control_record ();
1105 p->regexpr = xmalloc (len + 1);
1106 strncpy (p->regexpr, str + 1, len);
1107 p->re_compiled.allocated = len * 2;
1108 p->re_compiled.buffer = xmalloc (p->re_compiled.allocated);
1109 p->re_compiled.fastmap = xmalloc (1 << CHAR_BIT);
1110 p->re_compiled.translate = 0;
1111 err = re_compile_pattern (p->regexpr, len, &p->re_compiled);
1114 error (0, 0, _("%s: invalid regular expression: %s"), str, err);
1118 if (closing_delim[1])
1119 check_for_offset (p, str, closing_delim + 1);
1124 /* Extract the break patterns from args START through ARGC - 1 of ARGV.
1125 After each pattern, check if the next argument is a repeat count. */
1128 parse_patterns (int argc, int start, char **argv)
1130 int i; /* Index into ARGV. */
1131 struct control *p; /* New control record created. */
1133 static uintmax_t last_val = 0;
1135 for (i = start; i < argc; i++)
1137 if (*argv[i] == '/' || *argv[i] == '%')
1139 p = extract_regexp (i, *argv[i] == '%', argv[i]);
1143 p = new_control_record ();
1146 if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
1147 error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
1149 error (EXIT_FAILURE, 0,
1150 _("%s: line number must be greater than zero"),
1154 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
1155 error (EXIT_FAILURE, 0,
1156 _("line number `%s' is smaller than preceding line number, %s"),
1157 argv[i], umaxtostr (last_val, buf));
1160 if (val == last_val)
1162 _("warning: line number `%s' is the same as preceding line number"),
1167 p->lines_required = val;
1170 if (i + 1 < argc && *argv[i + 1] == '{')
1172 /* We have a repeat count. */
1174 parse_repeat_count (i, p, argv[i]);
1180 get_format_flags (char **format_ptr)
1182 unsigned int count = 0;
1184 for (; **format_ptr; (*format_ptr)++)
1186 switch (**format_ptr)
1197 count |= 2; /* Allow for 0x prefix preceding an `x' conversion. */
1208 get_format_width (char **format_ptr)
1210 unsigned long int val = 0;
1212 if (ISDIGIT (**format_ptr)
1213 && (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
1215 error (EXIT_FAILURE, 0, _("invalid format width"));
1217 /* Allow for enough octal digits to represent the value of UINT_MAX,
1218 even if the field width is less than that. */
1219 return MAX (val, (sizeof (unsigned int) * CHAR_BIT + 2) / 3);
1223 get_format_prec (char **format_ptr)
1225 if (**format_ptr != '.')
1229 if (! ISDIGIT (**format_ptr))
1233 unsigned long int val;
1234 if (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
1236 error (EXIT_FAILURE, 0, _("invalid format precision"));
1242 get_format_conv_type (char **format_ptr)
1244 unsigned char ch = *(*format_ptr)++;
1257 error (EXIT_FAILURE, 0, _("missing conversion specifier in suffix"));
1262 error (EXIT_FAILURE, 0,
1263 _("invalid conversion specifier in suffix: %c"), ch);
1265 error (EXIT_FAILURE, 0,
1266 _("invalid conversion specifier in suffix: \\%.3o"), ch);
1271 max_out (char *format)
1273 size_t out_count = 0;
1274 bool percent = false;
1278 if (*format++ != '%')
1280 else if (*format == '%')
1288 error (EXIT_FAILURE, 0,
1289 _("too many %% conversion specifications in suffix"));
1291 out_count += get_format_flags (&format);
1293 size_t width = get_format_width (&format);
1294 size_t prec = get_format_prec (&format);
1296 out_count += MAX (width, prec);
1298 get_format_conv_type (&format);
1303 error (EXIT_FAILURE, 0,
1304 _("missing %% conversion specification in suffix"));
1310 main (int argc, char **argv)
1313 unsigned long int val;
1315 initialize_main (&argc, &argv);
1316 program_name = argv[0];
1317 setlocale (LC_ALL, "");
1318 bindtextdomain (PACKAGE, LOCALEDIR);
1319 textdomain (PACKAGE);
1321 atexit (close_stdout);
1326 suppress_count = false;
1327 remove_files = true;
1328 prefix = DEFAULT_PREFIX;
1330 /* Change the way xmalloc and xrealloc fail. */
1331 xalloc_fail_func = cleanup;
1333 while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, NULL)) != -1)
1348 remove_files = false;
1352 if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
1354 error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
1360 suppress_count = true;
1364 elide_empty_files = true;
1367 case_GETOPT_HELP_CHAR;
1369 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1372 usage (EXIT_FAILURE);
1375 if (argc - optind < 2)
1377 error (0, 0, _("too few arguments"));
1378 usage (EXIT_FAILURE);
1382 filename_space = xmalloc (strlen (prefix) + max_out (suffix) + 2);
1384 filename_space = xmalloc (strlen (prefix) + digits + 2);
1386 set_input_file (argv[optind++]);
1388 parse_patterns (argc, optind, argv);
1392 static int const sig[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM };
1393 enum { nsigs = sizeof sig / sizeof sig[0] };
1396 struct sigaction act;
1398 sigemptyset (&caught_signals);
1399 for (i = 0; i < nsigs; i++)
1401 sigaction (sig[i], NULL, &act);
1402 if (act.sa_handler != SIG_IGN)
1403 sigaddset (&caught_signals, sig[i]);
1406 act.sa_handler = interrupt_handler;
1407 act.sa_mask = caught_signals;
1410 for (i = 0; i < nsigs; i++)
1411 if (sigismember (&caught_signals, sig[i]))
1412 sigaction (sig[i], &act, NULL);
1414 for (i = 0; i < nsigs; i++)
1415 if (signal (sig[i], SIG_IGN) != SIG_IGN)
1416 signal (sig[i], interrupt_handler);
1422 if (close (input_desc) < 0)
1424 error (0, errno, _("read error"));
1428 exit (EXIT_SUCCESS);
1434 if (status != EXIT_SUCCESS)
1435 fprintf (stderr, _("Try `%s --help' for more information.\n"),
1440 Usage: %s [OPTION]... FILE PATTERN...\n\
1444 Output pieces of FILE separated by PATTERN(s) to files `xx01', `xx02', ...,\n\
1445 and output byte counts of each piece to standard output.\n\
1449 Mandatory arguments to long options are mandatory for short options too.\n\
1452 -b, --suffix-format=FORMAT use sprintf FORMAT instead of %02d\n\
1453 -f, --prefix=PREFIX use PREFIX instead of `xx'\n\
1454 -k, --keep-files do not remove output files on errors\n\
1457 -n, --digits=DIGITS use specified number of digits instead of 2\n\
1458 -s, --quiet, --silent do not print counts of output file sizes\n\
1459 -z, --elide-empty-files remove empty output files\n\
1461 fputs (HELP_OPTION_DESCRIPTION, stdout);
1462 fputs (VERSION_OPTION_DESCRIPTION, stdout);
1465 Read standard input if FILE is -. Each PATTERN may be:\n\
1469 INTEGER copy up to but not including specified line number\n\
1470 /REGEXP/[OFFSET] copy up to but not including a matching line\n\
1471 %REGEXP%[OFFSET] skip to, but not including a matching line\n\
1472 {INTEGER} repeat the previous pattern specified number of times\n\
1473 {*} repeat the previous pattern as many times as possible\n\
1475 A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
1477 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);