interpret \ as an escape char in break_token
So: vips_break_token( "hello\ world", " " ) Sees a single token, `"hello world"`. This means you can now do things like: $ vips arrayjoin "k\ 2.jpg" x.png Where "k 2.jpg" is a filename containing a space. See https://github.com/libvips/libvips/issues/1493
This commit is contained in:
parent
c14d7c254b
commit
f8c7f9dac9
@ -2,6 +2,7 @@
|
|||||||
- more conformat IIIF output from dzsave [regisrob]
|
- more conformat IIIF output from dzsave [regisrob]
|
||||||
- add @id to dzsave to set IIIF id property [regisrob]
|
- add @id to dzsave to set IIIF id property [regisrob]
|
||||||
- add max and min to region shrink [rgluskin]
|
- add max and min to region shrink [rgluskin]
|
||||||
|
- allow \ as an escape character in vips_break_token() [akemrir]
|
||||||
|
|
||||||
20/6/19 started 8.9.1
|
20/6/19 started 8.9.1
|
||||||
- don't use the new source loaders for new_from_file or new_from_buffer, it
|
- don't use the new source loaders for new_from_file or new_from_buffer, it
|
||||||
|
@ -357,10 +357,46 @@ vips_isprefix( const char *a, const char *b )
|
|||||||
return( TRUE );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Exactly like strcspn(), but allow \ as an escape character.
|
||||||
|
*
|
||||||
|
* strspne( "hello world", " " ) == 5
|
||||||
|
* strspne( "hello\\ world", " " ) == 12
|
||||||
|
*/
|
||||||
|
static size_t
|
||||||
|
strcspne( const char *s, const char *reject )
|
||||||
|
{
|
||||||
|
size_t skip;
|
||||||
|
|
||||||
|
/* If \ is one of the reject chars, no need for any looping.
|
||||||
|
*/
|
||||||
|
if( strchr( reject, '\\' ) )
|
||||||
|
return( strcspn( s, reject ) );
|
||||||
|
|
||||||
|
skip = 0;
|
||||||
|
for(;;) {
|
||||||
|
skip += strcspn( s + skip, reject );
|
||||||
|
|
||||||
|
/* s[skip] is at the start of the string, or the end, or on a
|
||||||
|
* break character.
|
||||||
|
*/
|
||||||
|
if( skip == 0 ||
|
||||||
|
!s[skip] ||
|
||||||
|
s[skip - 1] != '\\' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* So skip points at break char and we have a '\' in the char
|
||||||
|
* before. Step over the break.
|
||||||
|
*/
|
||||||
|
skip += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( skip );
|
||||||
|
}
|
||||||
|
|
||||||
/* Like strtok(). Give a string and a list of break characters. Then:
|
/* Like strtok(). Give a string and a list of break characters. Then:
|
||||||
* - skip initial break characters
|
* - skip initial break characters
|
||||||
* - EOS? return NULL
|
* - EOS? return NULL
|
||||||
* - skip a series of non-break characters
|
* - skip a series of non-break characters, allow `\` as a break escape
|
||||||
* - write a '\0' over the next break character and return a pointer to the
|
* - write a '\0' over the next break character and return a pointer to the
|
||||||
* char after that
|
* char after that
|
||||||
*
|
*
|
||||||
@ -388,15 +424,22 @@ vips_isprefix( const char *a, const char *b )
|
|||||||
*
|
*
|
||||||
* for( i = 0; p; p = vips_break_token( p, " " ) )
|
* for( i = 0; p; p = vips_break_token( p, " " ) )
|
||||||
* v[i] = atoi( p );
|
* v[i] = atoi( p );
|
||||||
|
*
|
||||||
|
* You can use \ to escape breaks, for example:
|
||||||
|
*
|
||||||
|
* vips_break_token( "hello\ world", " " ) will see a single token containing
|
||||||
|
* a space. The \ characters are squashed out.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
vips_break_token( char *str, const char *brk )
|
vips_break_token( char *str, const char *brk )
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
char *q;
|
||||||
|
|
||||||
/* Is the string empty? If yes, return NULL immediately.
|
/* Is the string empty? If yes, return NULL immediately.
|
||||||
*/
|
*/
|
||||||
if( !str || !*str )
|
if( !str ||
|
||||||
|
!*str )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Skip initial break characters.
|
/* Skip initial break characters.
|
||||||
@ -409,9 +452,9 @@ vips_break_token( char *str, const char *brk )
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* We have a token ... search for the first break character after the
|
/* We have a token ... search for the first break character after the
|
||||||
* token.
|
* token. strcspne() allows '\' to escape breaks, see above.
|
||||||
*/
|
*/
|
||||||
p += strcspn( p, brk );
|
p += strcspne( p, brk );
|
||||||
|
|
||||||
/* Is there string left?
|
/* Is there string left?
|
||||||
*/
|
*/
|
||||||
@ -423,6 +466,17 @@ vips_break_token( char *str, const char *brk )
|
|||||||
p += strspn( p, brk );
|
p += strspn( p, brk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There may be escaped break characters in str. Loop, squashing them
|
||||||
|
* out.
|
||||||
|
*/
|
||||||
|
for( q = strchr( str, '\\' ); q && *q; q = strchr( q, '\\' ) ) {
|
||||||
|
memmove( q, q + 1, strlen( q ) );
|
||||||
|
|
||||||
|
/* If there's \\, we don't want to squash out the second \.
|
||||||
|
*/
|
||||||
|
q += 1;
|
||||||
|
}
|
||||||
|
|
||||||
return( p );
|
return( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user