#include #include #include #include #include "linecut.h" extern int errno; unsigned long count_lines (FILE *input) { unsigned long lines = 0; while (!feof (input)) if (fgetc (input) == '\n') lines++; return lines; } fpos_t * build_offset_map (data_t *gl) { unsigned long line = 0; fpos_t *map; map = xmalloc ((gl->lines_count + 1) * sizeof (fpos_t)); seek_to_start (gl); fgetpos (gl->input, &map[line]); while (!feof (gl->input)) if (fgetc (gl->input) == '\n') fgetpos (gl->input, &map[++line]); return map; } unsigned long map_stdin_lines (data_t *gl) { unsigned long i = 0, count = 1; char **lines; char buf[BUF_SIZE]; lines = xmalloc (sizeof (char *)); while (!feof (stdin)) { char *p, *s; fgets (buf, BUF_SIZE, stdin); s = buf; while ((p = strchr (s, '\n')) && !feof (stdin)) { char *str; unsigned int len; len = p - s; str = xmalloc (len + 1); strncpy (str, s, len); *(str + len) = '\0'; lines[i++] = str; lines = xrealloc (lines, ++count * sizeof (char *)); s = ++p; } } lines[i] = NULL; gl->stdin_lines = lines; return count - 1; } void seek_to_start (data_t *gl) { rewind (gl->input); } void seek_to_offset (data_t *gl, fpos_t *offset_map, long line) { short retval = fsetpos (gl->input, &offset_map[line]); if (retval != 0) { xfree (offset_map); error ("%s: could not seek to offset: %s", gl->file, strerror (errno)); } } void extract_range_file (data_t *gl, long range_start, long range_end) { const long start_line = range_start - 1; const long end_line = range_end - 1; long line = start_line; while (line <= end_line) { if (gl->number_lines) print_line_number (gl, line + 1); while (!feof (gl->input)) { char ch = fgetc (gl->input); if (is_char (ch)) put (ch); else { if (line++ <= end_line) put_newline (); break; } } } } void extract_range_stdin (data_t *gl, long range_start, long range_end) { const long start_line = range_start - 1; const long end_line = range_end - 1; long line; for (line = start_line; line <= end_line; line++) { if (gl->number_lines) print_line_number (gl, line + 1); fputs (gl->stdin_lines[line], stdout); put_newline (); } }