Charles E Campbell Jr wrote:
I've attached a patch to vim 7.1 which extends getfsize()

As I've mentioned, I think further testing will be needed before
patching Vim for 64-bit file lengths.

Here is a possible interim workaround to allow Dr.Chip's
LargeFile.vim script to accurately detect large files on many
platforms.

Attached is a tiny C program to build a tool called filemeg.
 Example usage:  filemeg /path/to/file
 gives output:   42

which means that the specified file is 42 megabytes (actually,
any value from 42 to nearly 43).

I was going to work out how to adapt the LargeFile script to use
this tool, if the user sets an option to invoke it. But it's
taking too long because I don't know enough about Vim, so I'm
just presenting the tool at this stage.

People may like to check how filemeg works on various systems
and report back. I have tried it on files over 4GB on Fedora
Core 6 and Windows XP (x86-32 platform).

Putting something like this inside Vim would be a bit of a
nightmare IMHO because of the extraordinary range of supported
compilers, operating systems and hardware.

Adapting LargeFile.vim to work with filemeg:
- Compile the source and test running at command line.
- Put the executable in your path (better: in a Vim
 directory which the script could invoke somehow).
- Set a new script option to use filemeg.
- The script BufReadPre would call a new script function.
- That function would check the file size with:
   let result = system('filemeg /path/to/file')
- If result is a number, it is the file size in megabytes.
- Otherwise, result is "Error..." and the script should
 treat the file as large (or maybe not...).

I've attached the C source, and included it below for those who
don't mind a little wrapping.

John

/* Output length of specified file in megabytes.
* John Beckett 2007/05/25
* For Linux with LFS (large file support), and Win32.
*
* Output is suitable for reading by a script.
* Output is always one line.
* If any problem occurs, line starts with "Error".
* Otherwise, line is the size of the specified file in megabytes.
* Size is a truncated integer (file of 3.9MB would give result "3").
* The size won't overflow a 32-bit signed integer ("Error" if it does).
* If argument is a directory, result is "0" (done by stat64()).
*/

#if defined(__linux)
# define _LARGEFILE64_SOURCE
#elif defined(_WIN32)
# define off64_t    __int64
# define stat64     _stati64
#endif

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
   off64_t size, overflowmask;
   struct stat64 sb;
   if ( argc != 2 ) {
       puts("Error: Need path of file to report its size in megabytes.");
       return 1;
   }
   if ( stat64(argv[1], &sb) != 0 ) {
       puts("Error: Could not get file information.");
       return 1;
   }
   size = sb.st_size >> 20;      /* 2^20 = 1 meg */
   overflowmask = 0x7fffffff;    /* ensure 64-bit calculation */
   if ( (size & ~overflowmask) != 0 ) {
puts("Error: File size in megabytes overflows 32-bit signed integer.");
       return 1;
   }
   printf("%d\n", (int)size);
   return 0;
}

Attachment: filemeg.c
Description: Binary data

Reply via email to