Skip to content

Instantly share code, notes, and snippets.

@jalbright015
Last active April 16, 2021 04:14
Show Gist options
  • Save jalbright015/909b53bac4d897877a31c14aeb9b52c8 to your computer and use it in GitHub Desktop.
Save jalbright015/909b53bac4d897877a31c14aeb9b52c8 to your computer and use it in GitHub Desktop.
Modified tail.c - Original by @gesslar
#include <driver/runtime_config.h>
// This function is expensive. It is also not compatible with
// old-style efun::tail() as 1) it acceptmp_size a second argument of
// the number of lines, and 2) it returns a string rather than
// printing out the resultmp_size.
//
// Did some significant changes to how it reads the file data
// and allocates lines for the return data. Based on my tests
// on a 120k file this reduced the execution time by over 99%.
// Jezu@Astaria 15 April 2021
varargs string tail(string file, int num_lines)
{
string *lines, *tmp, chunk;
int size, t1, t2, tmp_size, tmp_size2, lcut, bytes;
string ret = "";
seteuid( getuid( previous_object() ) );
if( nullp( file ) )
error("Missing arg 1 to tail()\n");
num_lines = num_lines || 25;
if( num_lines > 100 )
num_lines = 100;
size = file_size( file );
if( size < 1 )
return ret;
bytes = 1000;
if ( size < bytes )
bytes = size;
t1 = bytes;
tmp_size = 0;
tmp_size2 = 0;
lines = allocate(num_lines);
while ( tmp_size != num_lines )
{
chunk = read_bytes( file, size-t1, bytes);
lcut = strsrch(chunk, 10);
if ( lcut != -1 )
{
chunk = chunk[lcut..];
t1 -= lcut;
}
tmp = explode(chunk, "\n");
tmp_size = sizeof(tmp)+tmp_size;
if ( tmp_size > num_lines )
{
tmp = tmp[<(num_lines-tmp_size2)..];
tmp_size = num_lines;
}
lines[<tmp_size..<++tmp_size2] = tmp;
if ( t1 == size )
break;
tmp_size2 = tmp_size;
if ( size-t1 < bytes )
{
bytes = size-t1;
t1 = size;
}
else
t1 += bytes;
}
ret = implode(lines, "\n");
if ( sizeof(ret) > __LARGEST_PRINTABLE_STRING__ )
ret = ret[0..__LARGEST_PRINTABLE_STRING__];
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment