}
static off_t
-find_seek_offset_clrscr (FILE * fp)
+find_last_string_in_file(FILE * fp, const char *seq)
{
- off_t raw_seek_offset = 0;
- off_t seek_offset_clrscr;
- char *buf;
- struct stat mystat;
- int state = 0;
- int i;
- int bytesread;
+ char buf[512];
+ struct stat mystat;
+ off_t offset = 0L;
+ const long readsz = sizeof(buf);
+ int bytes_read = 0;
+ const int seqlen = strlen(seq);
+ const char *reset_pos = seq + seqlen - 1;
+ const char *match_pos = reset_pos;
+
+ fstat(fileno (fp), &mystat);
+ offset = mystat.st_size - readsz;
+ if (offset < 0)
+ offset = 0;
+ while (1)
+ {
+ const char *search_pos = 0;
- fstat (fileno (fp), &mystat);
- buf = malloc (mystat.st_size);
- fseek (fp, 0, SEEK_SET);
- bytesread = fread (buf, 1, mystat.st_size, fp);
+ fseeko(fp, offset, SEEK_SET);
+ bytes_read = fread(buf, 1, readsz, fp);
- /* one byte at at time sucks, but is a simple hack for the temp
- * being to avoid looking for wraparounds */
- for (i = 0; i < bytesread; i++)
- {
- if (buf[i] == 0x1b)
- {
- state = 1;
- }
- else if ((buf[i] == 0x5b) && (state == 1))
- {
- state = 2;
- }
- else if ((buf[i] == 0x32) && (state == 2))
- {
- state = 3;
- }
- else if ((buf[i] == 0x4a) && ((state == 2) || (state == 3)))
- {
- state = 4;
- }
- else
- {
- state = 0;
- }
+ if (bytes_read <= 0)
+ break;
- if (state == 4)
+ search_pos = buf + bytes_read - 1;
+ while (search_pos >= buf)
{
- raw_seek_offset = i - 2;
+ int matched = *search_pos == *match_pos;
+ if (!matched && match_pos != reset_pos)
+ {
+ match_pos = reset_pos;
+ matched = *search_pos == *match_pos;
+ }
+ if (matched)
+ {
+ if (match_pos == seq)
+ return offset + (search_pos - buf);
+ --match_pos;
+ }
+ --search_pos;
}
+
+ // If we've reached the start of the file, exit.
+ if (!offset)
+ break;
+
+ offset -= readsz;
+ if (offset < 0)
+ offset = 0;
}
- free (buf);
+ return 0;
+}
+
+static off_t
+find_seek_offset_clrscr (FILE * fp)
+{
+ off_t raw_seek_offset = 0;
+ off_t seek_offset_clrscr;
+
+ raw_seek_offset = find_last_string_in_file(fp, "\033[2J");
seek_offset_clrscr = 0;
/* now find last filepos that is less than seek offset */
{
char *buf;
Header h;
+ long offset;
if (ttyread (fp, &h, &buf, 0) != READ_DATA)
{
break;
}
- if (ftell (fp) < raw_seek_offset)
- {
- seek_offset_clrscr = ftell (fp);
- }
-
free (buf);
+
+ offset = ftell(fp);
+ if (offset < raw_seek_offset)
+ seek_offset_clrscr = ftell (fp);
+ else
+ break;
}
return seek_offset_clrscr;