better vips7 filename splitting
helps windows, see https://github.com/jcupitt/build-win32/issues/11 also add some tests
This commit is contained in:
parent
2b2ac1b077
commit
368a74abcd
@ -55,11 +55,22 @@
|
|||||||
* FILENAME_MAX chars.
|
* FILENAME_MAX chars.
|
||||||
*
|
*
|
||||||
* We look for the ':' splitting the name and mode by searching for the
|
* We look for the ':' splitting the name and mode by searching for the
|
||||||
* rightmost occurence of the regexp ".[A-Za-z0-9]+:". Example: consider the
|
* rightmost occurrence of the regexp "\.[A-Za-z0-9]+:". The initial dot can
|
||||||
* horror that is
|
* be missing if there's a dirsep or start of string, meaning this is a
|
||||||
|
* filename without an extension.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
*
|
*
|
||||||
* c:\silly:dir:name\fr:ed.tif:jpeg:95,,,,c:\icc\srgb.icc
|
* c:\silly:dir:name\fr:ed.tif:jpeg:95,,,,c:\icc\srgb.icc
|
||||||
|
* -> c:\silly:dir:name\fr:ed.tif jpeg:95,,,,c:\icc\srgb.icc
|
||||||
|
* I180:
|
||||||
|
* -> I180 ""
|
||||||
|
* c:\silly:
|
||||||
|
* -> c:\silly ""
|
||||||
|
* c:\silly
|
||||||
|
* -> c:\silly ""
|
||||||
*
|
*
|
||||||
|
* vips8 handles this in a much better way :(
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
im_filename_split( const char *path, char *name, char *mode )
|
im_filename_split( const char *path, char *name, char *mode )
|
||||||
@ -74,11 +85,15 @@ im_filename_split( const char *path, char *name, char *mode )
|
|||||||
if( *p == ':' ) {
|
if( *p == ':' ) {
|
||||||
char *q;
|
char *q;
|
||||||
|
|
||||||
|
/* We are skipping back over the file extension,
|
||||||
|
* isalnum() is probably sufficient.
|
||||||
|
*/
|
||||||
for( q = p - 1; isalnum( *q ) && q > name; q -= 1 )
|
for( q = p - 1; isalnum( *q ) && q > name; q -= 1 )
|
||||||
;
|
;
|
||||||
|
|
||||||
if( *q == '.' )
|
if( *q == '.' ) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* All the way back to the start? We probably have a
|
/* All the way back to the start? We probably have a
|
||||||
* filename with no extension, eg. "I180:"
|
* filename with no extension, eg. "I180:"
|
||||||
@ -86,9 +101,11 @@ im_filename_split( const char *path, char *name, char *mode )
|
|||||||
if( q == name )
|
if( q == name )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* .. or we could hit a dirsep.
|
/* .. or we could hit a dirsep. Allow win or nix
|
||||||
|
* separators.
|
||||||
*/
|
*/
|
||||||
if( *q == G_DIR_SEPARATOR )
|
if( *q == '/' ||
|
||||||
|
*q == '\\' )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +117,40 @@ im_filename_split( const char *path, char *name, char *mode )
|
|||||||
strcpy( mode, "" );
|
strcpy( mode, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_path_filename7:
|
||||||
|
* @path: path to split
|
||||||
|
*
|
||||||
|
* Return the filename part of a vips7 path. For testing only.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
vips_path_filename7( const char *path )
|
||||||
|
{
|
||||||
|
char name[FILENAME_MAX];
|
||||||
|
char mode[FILENAME_MAX];
|
||||||
|
|
||||||
|
im_filename_split( path, name, mode );
|
||||||
|
|
||||||
|
return( g_strdup( name ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_path_mode7:
|
||||||
|
* @path: path to split
|
||||||
|
*
|
||||||
|
* Return the mode part of a vips7 path. For testing only.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
vips_path_mode7( const char *path )
|
||||||
|
{
|
||||||
|
char name[FILENAME_MAX];
|
||||||
|
char mode[FILENAME_MAX];
|
||||||
|
|
||||||
|
im_filename_split( path, name, mode );
|
||||||
|
|
||||||
|
return( g_strdup( mode ) );
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip any leading path stuff. Horrible: if this is a filename which came
|
/* Skip any leading path stuff. Horrible: if this is a filename which came
|
||||||
* from win32 and we're a *nix machine, it'll have '\\' not '/' as the
|
* from win32 and we're a *nix machine, it'll have '\\' not '/' as the
|
||||||
* separator :-(
|
* separator :-(
|
||||||
|
@ -66,6 +66,11 @@ typedef enum {
|
|||||||
VIPS_PRECISION_LAST
|
VIPS_PRECISION_LAST
|
||||||
} VipsPrecision;
|
} VipsPrecision;
|
||||||
|
|
||||||
|
/* Just for testing.
|
||||||
|
*/
|
||||||
|
char *vips_path_filename7( const char *path );
|
||||||
|
char *vips_path_mode7( const char *path );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
@ -13,6 +13,7 @@ EXTRA_DIST = \
|
|||||||
test_colour.py \
|
test_colour.py \
|
||||||
test_conversion.py \
|
test_conversion.py \
|
||||||
test_convolution.py \
|
test_convolution.py \
|
||||||
|
test_iofuncs.py \
|
||||||
test_create.py \
|
test_create.py \
|
||||||
test_foreign.py \
|
test_foreign.py \
|
||||||
test_draw.py \
|
test_draw.py \
|
||||||
|
@ -12,6 +12,7 @@ from test_foreign import *
|
|||||||
from test_histogram import *
|
from test_histogram import *
|
||||||
from test_morphology import *
|
from test_morphology import *
|
||||||
from test_resample import *
|
from test_resample import *
|
||||||
|
from test_iofuncs import *
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
61
test/test_iofuncs.py
Executable file
61
test/test_iofuncs.py
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
import unittest
|
||||||
|
import math
|
||||||
|
|
||||||
|
#import logging
|
||||||
|
#logging.basicConfig(level = logging.DEBUG)
|
||||||
|
|
||||||
|
from gi.repository import Vips
|
||||||
|
|
||||||
|
Vips.leak_set(True)
|
||||||
|
|
||||||
|
# an expanding zip ... if either of the args is not a list, duplicate it down
|
||||||
|
# the other
|
||||||
|
def zip_expand(x, y):
|
||||||
|
if isinstance(x, list) and isinstance(y, list):
|
||||||
|
return list(zip(x, y))
|
||||||
|
elif isinstance(x, list):
|
||||||
|
return [[i, y] for i in x]
|
||||||
|
elif isinstance(y, list):
|
||||||
|
return [[x, j] for j in y]
|
||||||
|
else:
|
||||||
|
return [[x, y]]
|
||||||
|
|
||||||
|
class TestIofuncs(unittest.TestCase):
|
||||||
|
# test a pair of things which can be lists for approx. equality
|
||||||
|
def assertEqualObjects(self, a, b, msg = ''):
|
||||||
|
#print('assertEqualObjects %s = %s' % (a, b))
|
||||||
|
for x, y in zip_expand(a, b):
|
||||||
|
self.assertEqual(x, y, msg = msg)
|
||||||
|
|
||||||
|
# test the vips7 filename splitter ... this is very fragile and annoying
|
||||||
|
# code with lots of cases
|
||||||
|
def test_split7(self):
|
||||||
|
def split(path):
|
||||||
|
filename7 = Vips.path_filename7(path)
|
||||||
|
mode7 = Vips.path_mode7(path)
|
||||||
|
|
||||||
|
return [filename7, mode7]
|
||||||
|
|
||||||
|
cases = [
|
||||||
|
["c:\\silly:dir:name\\fr:ed.tif:jpeg:95,,,,c:\\icc\\srgb.icc",
|
||||||
|
["c:\\silly:dir:name\\fr:ed.tif",
|
||||||
|
"jpeg:95,,,,c:\\icc\\srgb.icc"]],
|
||||||
|
["I180:",
|
||||||
|
["I180",
|
||||||
|
""]],
|
||||||
|
["c:\\silly:",
|
||||||
|
["c:\\silly",
|
||||||
|
""]],
|
||||||
|
["c:\\program files\\x:hello",
|
||||||
|
["c:\\program files\\x",
|
||||||
|
"hello"]]
|
||||||
|
]
|
||||||
|
|
||||||
|
for case in cases:
|
||||||
|
self.assertEqualObjects(split(case[0]), case[1])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user