1 /* Some basic util functions.
2 */
3
4 /*
5
6 Copyright (C) 1991-2003 The National Gallery
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301 USA
22
23 */
24
25 /*
26
27 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
28
29 */
30
31 /*
32 #define DEBUG
33 */
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif /*HAVE_CONFIG_H*/
38 #include <vips/intl.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <ctype.h>
44 #include <errno.h>
45
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif /*HAVE_UNISTD_H*/
51 #ifdef HAVE_IO_H
52 #include <io.h>
53 #endif /*HAVE_IO_H*/
54 #include <fcntl.h>
55
56 #include <vips/vips.h>
57
58 #ifdef G_OS_WIN32
59 #include <windows.h>
60 #endif /*G_OS_WIN32*/
61
62 #include <vips/debug.h>
63 #include <vips/internal.h>
64
65 /* Temp buffer for snprintf() layer on old systems.
66 */
67 #define MAX_BUF (100000)
68
69 #define MODE_READ CLOEXEC (BINARYIZE (O_RDONLY))
70
71 /* Test two lists for eqality.
72 */
73 gboolean
vips_slist_equal(GSList * l1,GSList * l2)74 vips_slist_equal( GSList *l1, GSList *l2 )
75 {
76 while( l1 && l2 ) {
77 if( l1->data != l2->data )
78 return( FALSE );
79
80 l1 = l1->next;
81 l2 = l2->next;
82 }
83
84 if( l1 || l2 )
85 return( FALSE );
86
87 return( TRUE );
88 }
89
90 /* Map over an slist. _copy() the list in case the callback changes it.
91 */
92 void *
vips_slist_map2(GSList * list,VipsSListMap2Fn fn,void * a,void * b)93 vips_slist_map2( GSList *list, VipsSListMap2Fn fn, void *a, void *b )
94 {
95 GSList *copy;
96 GSList *i;
97 void *result;
98
99 copy = g_slist_copy( list );
100 result = NULL;
101 for( i = copy; i && !(result = fn( i->data, a, b )); i = i->next )
102 ;
103 g_slist_free( copy );
104
105 return( result );
106 }
107
108 /* Map backwards. We _reverse() rather than recurse and unwind to save stack.
109 */
110 void *
vips_slist_map2_rev(GSList * list,VipsSListMap2Fn fn,void * a,void * b)111 vips_slist_map2_rev( GSList *list, VipsSListMap2Fn fn, void *a, void *b )
112 {
113 GSList *copy;
114 GSList *i;
115 void *result;
116
117 copy = g_slist_copy( list );
118 copy = g_slist_reverse( copy );
119 result = NULL;
120 for( i = copy; i && !(result = fn( i->data, a, b )); i = i->next )
121 ;
122 g_slist_free( copy );
123
124 return( result );
125 }
126
127 void *
vips_slist_map4(GSList * list,VipsSListMap4Fn fn,void * a,void * b,void * c,void * d)128 vips_slist_map4( GSList *list,
129 VipsSListMap4Fn fn, void *a, void *b, void *c, void *d )
130 {
131 GSList *copy;
132 GSList *i;
133 void *result;
134
135 copy = g_slist_copy( list );
136 result = NULL;
137 for( i = copy;
138 i && !(result = fn( i->data, a, b, c, d )); i = i->next )
139 ;
140 g_slist_free( copy );
141
142 return( result );
143 }
144
145 void *
vips_slist_fold2(GSList * list,void * start,VipsSListFold2Fn fn,void * a,void * b)146 vips_slist_fold2( GSList *list, void *start,
147 VipsSListFold2Fn fn, void *a, void *b )
148 {
149 void *c;
150 GSList *this, *next;
151
152 for( c = start, this = list; this; this = next ) {
153 next = this->next;
154
155 if( !(c = fn( this->data, c, a, b )) )
156 return( NULL );
157 }
158
159 return( c );
160 }
161
162 /* Remove all occurences of an item from a list.
163 */
164 GSList *
vips_slist_filter(GSList * list,VipsSListMap2Fn fn,void * a,void * b)165 vips_slist_filter( GSList *list, VipsSListMap2Fn fn, void *a, void *b )
166 {
167 GSList *tmp;
168 GSList *prev;
169
170 prev = NULL;
171 tmp = list;
172
173 while( tmp ) {
174 if( fn( tmp->data, a, b ) ) {
175 GSList *next = tmp->next;
176
177 if( prev )
178 prev->next = next;
179 if( list == tmp )
180 list = next;
181
182 tmp->next = NULL;
183 g_slist_free( tmp );
184 tmp = next;
185 }
186 else {
187 prev = tmp;
188 tmp = tmp->next;
189 }
190 }
191
192 return( list );
193 }
194
195 static void
vips_slist_free_all_cb(void * thing,void * dummy)196 vips_slist_free_all_cb( void * thing, void * dummy )
197 {
198 g_free( thing );
199 }
200
201 /* Free a g_slist of things which need g_free()ing.
202 */
203 void
vips_slist_free_all(GSList * list)204 vips_slist_free_all( GSList *list )
205 {
206 g_slist_foreach( list, vips_slist_free_all_cb, NULL );
207 g_slist_free( list );
208 }
209
210 void *
vips_map_equal(void * a,void * b)211 vips_map_equal( void *a, void *b )
212 {
213 if( a == b )
214 return( a );
215
216 return( NULL );
217 }
218
219 typedef struct {
220 void *a;
221 void *b;
222 VipsSListMap2Fn fn;
223 void *result;
224 } Pair;
225
226 static gboolean
vips_hash_table_predicate(const char * key,void * value,Pair * pair)227 vips_hash_table_predicate( const char *key, void *value, Pair *pair )
228 {
229 return( (pair->result = pair->fn( value, pair->a, pair->b )) != NULL );
230 }
231
232 /* Like slist map, but for a hash table.
233 */
234 void *
vips_hash_table_map(GHashTable * hash,VipsSListMap2Fn fn,void * a,void * b)235 vips_hash_table_map( GHashTable *hash, VipsSListMap2Fn fn, void *a, void *b )
236 {
237 Pair pair;
238
239 pair.a = a;
240 pair.b = b;
241 pair.fn = fn;
242 pair.result = NULL;
243
244 g_hash_table_find( hash, (GHRFunc) vips_hash_table_predicate, &pair );
245
246 return( pair.result );
247 }
248
249 /* Like strncpy(), but always NULL-terminate, and don't pad with NULLs.
250 * If @n is 100 and @src is more than 99 characters, 99 are copied and the
251 * final byte of @dest is set to '\0'.
252 */
253 char *
vips_strncpy(char * dest,const char * src,int n)254 vips_strncpy( char *dest, const char *src, int n )
255 {
256 int i;
257
258 g_assert( n > 0 );
259
260 for( i = 0; i < n - 1; i++ )
261 if( !(dest[i] = src[i]) )
262 break;
263 dest[i] = '\0';
264
265 return( dest );
266 }
267
268 /* Find the rightmost occurrence of needle in haystack.
269 */
270 char *
vips_strrstr(const char * haystack,const char * needle)271 vips_strrstr( const char *haystack, const char *needle )
272 {
273 int haystack_len = strlen( haystack );
274 int needle_len = strlen( needle );
275 int i;
276
277 for( i = haystack_len - needle_len; i >= 0; i-- )
278 if( strncmp( needle, haystack + i, needle_len ) == 0 )
279 return( (char *) haystack + i );
280
281 return( NULL );
282 }
283
284 /* Test for string b ends string a.
285 */
286 gboolean
vips_ispostfix(const char * a,const char * b)287 vips_ispostfix( const char *a, const char *b )
288 {
289 int m = strlen( a );
290 int n = strlen( b );
291
292 if( n > m )
293 return( FALSE );
294
295 return( strcmp( a + m - n, b ) == 0 );
296 }
297
298 /* Case-insensitive test for string b ends string a. ASCII strings only.
299 */
300 gboolean
vips_iscasepostfix(const char * a,const char * b)301 vips_iscasepostfix( const char *a, const char *b )
302 {
303 int m = strlen( a );
304 int n = strlen( b );
305
306 if( n > m )
307 return( FALSE );
308
309 return( g_ascii_strcasecmp( a + m - n, b ) == 0 );
310 }
311
312 /* Test for string a starts string b. a is a known-good string, b may be
313 * random data.
314 */
315 gboolean
vips_isprefix(const char * a,const char * b)316 vips_isprefix( const char *a, const char *b )
317 {
318 int i;
319
320 for( i = 0; a[i] && b[i]; i++ )
321 if( a[i] != b[i] )
322 return( FALSE );
323
324 /* If there's stuff left in a but b has finished, we must have a
325 * mismatch.
326 */
327 if( a[i] && !b[i] )
328 return( FALSE );
329
330 return( TRUE );
331 }
332
333 /* Exactly like strcspn(), but allow \ as an escape character.
334 *
335 * strspne( "hello world", " " ) == 5
336 * strspne( "hello\\ world", " " ) == 12
337 */
338 static size_t
strcspne(const char * s,const char * reject)339 strcspne( const char *s, const char *reject )
340 {
341 size_t skip;
342
343 /* If \ is one of the reject chars, no need for any looping.
344 */
345 if( strchr( reject, '\\' ) )
346 return( strcspn( s, reject ) );
347
348 skip = 0;
349 for(;;) {
350 skip += strcspn( s + skip, reject );
351
352 /* s[skip] is at the start of the string, or the end, or on a
353 * break character.
354 */
355 if( skip == 0 ||
356 !s[skip] ||
357 s[skip - 1] != '\\' )
358 break;
359
360 /* So skip points at break char and we have a '\' in the char
361 * before. Step over the break.
362 */
363 skip += 1;
364 }
365
366 return( skip );
367 }
368
369 /* Like strtok(). Give a string and a list of break characters. Then:
370 * - skip initial break characters
371 * - EOS? return NULL
372 * - skip a series of non-break characters, allow `\` as a break escape
373 * - write a '\0' over the next break character and return a pointer to the
374 * char after that
375 *
376 * The idea is that this can be used in loops as the iterator. Example:
377 *
378 * char *p = " 1 2 3 "; // mutable
379 * char *q;
380 * int i;
381 * int v[...];
382 *
383 * for( i = 0; (q = vips_break_token( p, " " )); i++, p = q )
384 * v[i] = atoi( p );
385 *
386 * will set
387 * v[0] = 1;
388 * v[1] = 2;
389 * v[2] = 3;
390 *
391 * or with just one pointer, provided your atoi() is OK with trailing chars
392 * and you know there is at least one item there
393 *
394 * char *p = " 1 2 3 "; // mutable
395 * int i;
396 * int v[...];
397 *
398 * for( i = 0; p; p = vips_break_token( p, " " ) )
399 * v[i] = atoi( p );
400 *
401 * You can use \ to escape breaks, for example:
402 *
403 * vips_break_token( "hello\ world", " " ) will see a single token containing
404 * a space. The \ characters are squashed out.
405 */
406 char *
vips_break_token(char * str,const char * brk)407 vips_break_token( char *str, const char *brk )
408 {
409 char *p;
410 char *q;
411
412 /* Is the string empty? If yes, return NULL immediately.
413 */
414 if( !str ||
415 !*str )
416 return( NULL );
417
418 /* Skip initial break characters.
419 */
420 p = str + strspn( str, brk );
421
422 /* No item?
423 */
424 if( !*p )
425 return( NULL );
426
427 /* We have a token ... search for the first break character after the
428 * token. strcspne() allows '\' to escape breaks, see above.
429 */
430 p += strcspne( p, brk );
431
432 /* Is there string left?
433 */
434 if( *p ) {
435 /* Write in an end-of-string mark and return the start of the
436 * next token.
437 */
438 *p++ = '\0';
439 p += strspn( p, brk );
440 }
441
442 /* There may be escaped break characters in str. Loop, squashing them
443 * out.
444 */
445 for( q = strchr( str, '\\' ); q && *q; q = strchr( q, '\\' ) ) {
446 memmove( q, q + 1, strlen( q ) );
447
448 /* If there's \\, we don't want to squash out the second \.
449 */
450 q += 1;
451 }
452
453 return( p );
454 }
455
456 /* Wrapper over (v)snprintf() ... missing on old systems.
457 */
458 int
vips_vsnprintf(char * str,size_t size,const char * format,va_list ap)459 vips_vsnprintf( char *str, size_t size, const char *format, va_list ap )
460 {
461 #ifdef HAVE_VSNPRINTF
462 return( vsnprintf( str, size, format, ap ) );
463 #else /*HAVE_VSNPRINTF*/
464 /* Bleurg!
465 */
466 int n;
467 static char buf[MAX_BUF];
468
469 /* We can't return an error code, we may already have trashed the
470 * stack. We must stop immediately.
471 */
472 if( size > MAX_BUF )
473 vips_error_exit( "panic: buffer overflow "
474 "(request to write %lu bytes to buffer of %d bytes)",
475 (unsigned long) size, MAX_BUF );
476 n = vsprintf( buf, format, ap );
477 if( n > MAX_BUF )
478 vips_error_exit( "panic: buffer overflow "
479 "(%d bytes written to buffer of %d bytes)",
480 n, MAX_BUF );
481
482 vips_strncpy( str, buf, size );
483
484 return( n );
485 #endif /*HAVE_VSNPRINTF*/
486 }
487
488 int
vips_snprintf(char * str,size_t size,const char * format,...)489 vips_snprintf( char *str, size_t size, const char *format, ... )
490 {
491 va_list ap;
492 int n;
493
494 va_start( ap, format );
495 n = vips_vsnprintf( str, size, format, ap );
496 va_end( ap );
497
498 return( n );
499 }
500
501 /* Does a filename have one of a set of suffixes. Ignore case and any trailing
502 * options.
503 */
504 int
vips_filename_suffix_match(const char * path,const char * suffixes[])505 vips_filename_suffix_match( const char *path, const char *suffixes[] )
506 {
507 char *basename;
508 char *q;
509 int result;
510 const char **p;
511
512 /* Drop any directory components.
513 */
514 basename = g_path_get_basename( path );
515
516 /* Zap any trailing [] options.
517 */
518 if( (q = (char *) vips__find_rightmost_brackets( basename )) )
519 *q = '\0';
520
521 result = 0;
522 for( p = suffixes; *p; p++ )
523 if( vips_iscasepostfix( basename, *p ) ) {
524 result = 1;
525 break;
526 }
527
528 g_free( basename );
529
530 return( result );
531 }
532
533 /* Get file length ... 64-bitally. -1 for error.
534 */
535 gint64
vips_file_length(int fd)536 vips_file_length( int fd )
537 {
538 #ifdef G_OS_WIN32
539 struct _stati64 st;
540
541 if( _fstati64( fd, &st ) == -1 ) {
542 #else /*!G_OS_WIN32*/
543 struct stat st;
544
545 if( fstat( fd, &st ) == -1 ) {
546 #endif /*G_OS_WIN32*/
547 vips_error_system( errno, "vips_file_length",
548 "%s", _( "unable to get file stats" ) );
549 return( -1 );
550 }
551
552 return( st.st_size );
553 }
554
555 /* Wrap write() up
556 */
557 int
558 vips__write( int fd, const void *buf, size_t count )
559 {
560 do {
561 size_t nwritten = write( fd, buf, count );
562
563 if( nwritten == (size_t) -1 ) {
564 vips_error_system( errno, "vips__write",
565 "%s", _( "write failed" ) );
566 return( -1 );
567 }
568
569 buf = (void *) ((char *) buf + nwritten);
570 count -= nwritten;
571 } while( count > 0 );
572
573 return( 0 );
574 }
575
576 #ifdef G_OS_WIN32
577 /* Set the create date on a file. On Windows, the create date may be copied
578 * over from an existing file of the same name, unless you reset it.
579 *
580 * See https://blogs.msdn.microsoft.com/oldnewthing/20050715-14/?p=34923
581 */
582 void
583 vips__set_create_time( int fd )
584 {
585 HANDLE handle;
586 SYSTEMTIME st;
587 FILETIME ft;
588
589 if( (handle = (HANDLE) _get_osfhandle( fd )) == INVALID_HANDLE_VALUE )
590 return;
591 GetSystemTime( &st );
592 SystemTimeToFileTime( &st, &ft );
593 SetFileTime( handle, &ft, &ft, &ft );
594 }
595 #endif /*G_OS_WIN32*/
596
597 /* open() with a utf8 filename, setting errno.
598 */
599 int
600 vips__open( const char *filename, int flags, int mode )
601 {
602 int fd;
603
604 /* Various bad things happen if you accidentally open a directory as a
605 * file.
606 */
607 if( g_file_test( filename, G_FILE_TEST_IS_DIR ) ) {
608 errno = EISDIR;
609 return( -1 );
610 }
611
612 fd = g_open( filename, flags, mode );
613
614 #ifdef G_OS_WIN32
615 if( mode & O_CREAT )
616 vips__set_create_time( fd );
617 #endif /*G_OS_WIN32*/
618
619 return( fd );
620 }
621
622 int
623 vips__open_read( const char *filename )
624 {
625 return( vips__open( filename, MODE_READ, 0 ) );
626 }
627
628 /* fopen() with utf8 filename and mode, setting errno.
629 */
630 FILE *
631 vips__fopen( const char *filename, const char *mode )
632 {
633 FILE *fp;
634
635 fp = g_fopen( filename, mode );
636
637 #ifdef G_OS_WIN32
638 if( mode[0] == 'w' )
639 vips__set_create_time( _fileno( fp ) );
640 #endif /*G_OS_WIN32*/
641
642 return( fp );
643 }
644
645 /* Does a filename contain a directory separator?
646 */
647 static gboolean
648 filename_hasdir( const char *filename )
649 {
650 char *dirname;
651 gboolean hasdir;
652
653 dirname = g_path_get_dirname( filename );
654 hasdir = (strcmp( dirname, "." ) != 0);
655 g_free( dirname );
656
657 return( hasdir );
658 }
659
660 /* Open a file. We take an optional fallback dir as well and will try opening
661 * there if opening directly fails.
662 *
663 * This is used for things like finding ICC profiles. We try to open the file
664 * directly first, and if that fails and the filename does not contain a
665 * directory separator, we try looking in the fallback dir.
666 */
667 FILE *
668 vips__file_open_read( const char *filename, const char *fallback_dir,
669 gboolean text_mode )
670 {
671 char *mode;
672 FILE *fp;
673
674 #if defined(G_PLATFORM_WIN32) || defined(G_WITH_CYGWIN)
675 if( text_mode )
676 mode = "rN";
677 else
678 mode = "rbN";
679 #else /*!defined(G_PLATFORM_WIN32) && !defined(G_WITH_CYGWIN)*/
680 mode = "re";
681 #endif /*defined(G_PLATFORM_WIN32) || defined(G_WITH_CYGWIN)*/
682
683 if( (fp = vips__fopen( filename, mode )) )
684 return( fp );
685
686 if( fallback_dir &&
687 !filename_hasdir( filename ) ) {
688 char *path;
689
690 path = g_build_filename( fallback_dir, filename, NULL );
691 fp = vips__fopen( path, mode );
692 g_free( path );
693
694 if( fp )
695 return( fp );
696 }
697
698 vips_error_system( errno, "vips__file_open_read",
699 _( "unable to open file \"%s\" for reading" ), filename );
700
701 return( NULL );
702 }
703
704 FILE *
705 vips__file_open_write( const char *filename, gboolean text_mode )
706 {
707 char *mode;
708 FILE *fp;
709
710 #if defined(G_PLATFORM_WIN32) || defined(G_WITH_CYGWIN)
711 if( text_mode )
712 mode = "wN";
713 else
714 mode = "wbN";
715 #else /*!defined(G_PLATFORM_WIN32) && !defined(G_WITH_CYGWIN)*/
716 mode = "we";
717 #endif /*defined(G_PLATFORM_WIN32) || defined(G_WITH_CYGWIN)*/
718
719 if( !(fp = vips__fopen( filename, mode )) ) {
720 vips_error_system( errno, "vips__file_open_write",
721 _( "unable to open file \"%s\" for writing" ),
722 filename );
723 return( NULL );
724 }
725
726 return( fp );
727 }
728
729 /* Load up a file as a string.
730 */
731 char *
732 vips__file_read( FILE *fp, const char *filename, size_t *length_out )
733 {
734 gint64 len;
735 size_t read;
736 char *str;
737
738 len = vips_file_length( fileno( fp ) );
739 if( len > 1024 * 1024 * 1024 ) {
740 /* Over a gb? Seems crazy!
741 */
742 vips_error( "vips__file_read",
743 _( "\"%s\" too long" ), filename );
744 return( NULL );
745 }
746
747 if( len == -1 ) {
748 int size;
749
750 /* Can't get length: read in chunks and realloc() to end of
751 * file.
752 */
753 str = NULL;
754 len = 0;
755 size = 0;
756 do {
757 char *str2;
758
759 /* Again, a 1gb sanity limit.
760 */
761 size += 1024;
762 if( size > 1024 * 1024 * 1024 ||
763 !(str2 = realloc( str, size )) ) {
764 free( str );
765 vips_error( "vips__file_read",
766 "%s", _( "out of memory" ) );
767 return( NULL );
768 }
769 str = str2;
770
771 /* -1 to allow space for an extra NULL we add later.
772 */
773 read = fread( str + len, sizeof( char ),
774 (size - len - 1) / sizeof( char ),
775 fp );
776 len += read;
777 } while( !feof( fp ) );
778
779 #ifdef DEBUG
780 printf( "read %ld bytes from unseekable stream\n", len );
781 #endif /*DEBUG*/
782 }
783 else {
784 /* Allocate memory and fill.
785 */
786 if( !(str = vips_malloc( NULL, len + 1 )) )
787 return( NULL );
788 rewind( fp );
789 read = fread( str, sizeof( char ), (size_t) len, fp );
790 if( read != (size_t) len ) {
791 g_free( str );
792 vips_error( "vips__file_read",
793 _( "error reading from file \"%s\"" ),
794 filename );
795 return( NULL );
796 }
797 }
798
799 str[len] = '\0';
800
801 if( length_out )
802 *length_out = len;
803
804 return( str );
805 }
806
807 /* Load from a filename as a string. Used for things like reading in ICC
808 * profiles, ie. binary objects.
809 */
810 char *
811 vips__file_read_name( const char *filename, const char *fallback_dir,
812 size_t *length_out )
813 {
814 FILE *fp;
815 char *buffer;
816
817 if( !(fp = vips__file_open_read( filename, fallback_dir, FALSE )) )
818 return( NULL );
819 if( !(buffer = vips__file_read( fp, filename, length_out )) ) {
820 fclose( fp );
821 return( NULL );
822 }
823 fclose( fp );
824
825 return( buffer );
826 }
827
828 /* Like fwrite(), but returns non-zero on error and sets error message.
829 */
830 int
831 vips__file_write( void *data, size_t size, size_t nmemb, FILE *stream )
832 {
833 size_t n;
834
835 if( !data )
836 return( 0 );
837
838 if( (n = fwrite( data, size, nmemb, stream )) != nmemb ) {
839 vips_error_system( errno, "vips__file_write",
840 _( "write error (%zd out of %zd blocks written)" ),
841 n, nmemb );
842 return( -1 );
843 }
844
845 return( 0 );
846 }
847
848 /* Read a few bytes from the start of a file. This is used for sniffing file
849 * types, so we must read binary.
850 *
851 * Return the number of bytes actually read (the file might be shorter than
852 * len), or -1 for error.
853 */
854 gint64
855 vips__get_bytes( const char *filename, unsigned char buf[], gint64 len )
856 {
857 int fd;
858 gint64 bytes_read;
859
860 /* File may not even exist (for tmp images for example!)
861 * so no hasty messages. And the file might be truncated, so no error
862 * on read either.
863 */
864 if( (fd = vips__open_read( filename )) == -1 )
865 return( 0 );
866 bytes_read = read( fd, buf, len );
867 close( fd );
868
869 return( bytes_read );
870 }
871
872 /* We try to support stupid DOS files too. These have \r\n (13, 10) as line
873 * separators. Strategy: an fgetc() that swaps \r\n for \n.
874 *
875 * On Windows, stdio will automatically swap \r\n for \n, but on Linux we have
876 * to do this by hand.
877 */
878 int
879 vips__fgetc( FILE *fp )
880 {
881 int ch;
882
883 ch = fgetc( fp );
884 if( ch == '\r' ) {
885 ch = fgetc( fp );
886 if( ch != '\n' ) {
887 ungetc( ch, fp );
888 ch = '\r';
889 }
890 }
891
892 return( ch );
893 }
894
895 /* Alloc/free a GValue.
896 */
897 static GValue *
898 vips__gvalue_new( GType type )
899 {
900 GValue *value;
901
902 value = g_new0( GValue, 1 );
903 g_value_init( value, type );
904
905 return( value );
906 }
907
908 static GValue *
909 vips__gvalue_copy( GValue *value )
910 {
911 GValue *value_copy;
912
913 value_copy = vips__gvalue_new( G_VALUE_TYPE( value ) );
914 g_value_copy( value, value_copy );
915
916 return( value_copy );
917 }
918
919 static void
920 vips__gvalue_free( GValue *value, void *user_data )
921 {
922 g_value_unset( value );
923 g_free( value );
924 }
925
926 GValue *
927 vips__gvalue_ref_string_new( const char *text )
928 {
929 GValue *value;
930
931 value = vips__gvalue_new( VIPS_TYPE_REF_STRING );
932 vips_value_set_ref_string( value, text );
933
934 return( value );
935 }
936
937 /* Free a GSList of GValue.
938 */
939 void
940 vips__gslist_gvalue_free( GSList *list )
941 {
942 g_slist_foreach( list, (GFunc) vips__gvalue_free, NULL );
943 g_slist_free( list );
944 }
945
946 /* Copy a GSList of GValue.
947 */
948 GSList *
949 vips__gslist_gvalue_copy( const GSList *list )
950 {
951 GSList *copy;
952 const GSList *p;
953
954 copy = NULL;
955
956 for( p = list; p; p = p->next )
957 copy = g_slist_prepend( copy,
958 vips__gvalue_copy( (GValue *) p->data ) );
959
960 copy = g_slist_reverse( copy );
961
962 return( copy );
963 }
964
965 /* Merge two GSList of GValue ... append to a all elements in b which are not
966 * in a. Return the new value of a. Works for any vips refcounted type
967 * (string, blob, etc.).
968 */
969 GSList *
970 vips__gslist_gvalue_merge( GSList *a, const GSList *b )
971 {
972 const GSList *i, *j;
973 GSList *tail;
974
975 tail = NULL;
976
977 for( i = b; i; i = i->next ) {
978 GValue *value = (GValue *) i->data;
979
980 g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
981
982 for( j = a; j; j = j->next ) {
983 GValue *value2 = (GValue *) j->data;
984
985 g_assert( G_VALUE_TYPE( value2 ) ==
986 VIPS_TYPE_REF_STRING );
987
988 /* Just do a pointer compare ... good enough 99.9% of
989 * the time.
990 */
991 if( vips_value_get_ref_string( value, NULL ) ==
992 vips_value_get_ref_string( value2, NULL ) )
993 break;
994 }
995
996 if( !j )
997 tail = g_slist_prepend( tail,
998 vips__gvalue_copy( value ) );
999 }
1000
1001 a = g_slist_concat( a, g_slist_reverse( tail ) );
1002
1003 return( a );
1004 }
1005
1006 /* Make a char * from GSList of GValue. Each GValue should be a ref_string.
1007 * free the result. Empty list -> "", not NULL. Join strings with '\n'.
1008 */
1009 char *
1010 vips__gslist_gvalue_get( const GSList *list )
1011 {
1012 const GSList *p;
1013 size_t length;
1014 char *all;
1015 char *q;
1016
1017 /* Need to estimate length first.
1018 */
1019 length = 0;
1020 for( p = list; p; p = p->next ) {
1021 GValue *value = (GValue *) p->data;
1022 size_t l2;
1023
1024 g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
1025
1026 /* +1 for the newline we will add for each item.
1027 */
1028 (void) vips_value_get_ref_string( value, &l2 );
1029 length += l2 + 1;
1030 }
1031
1032 if( length == 0 )
1033 return( NULL );
1034
1035 /* More than 10MB of history? Madness!
1036 */
1037 g_assert( length < 10 * 1024 * 1024 );
1038
1039 /* +1 for '\0'.
1040 */
1041 if( !(all = vips_malloc( NULL, length + 1 )) )
1042 return( NULL );
1043
1044 q = all;
1045 for( p = list; p; p = p->next ) {
1046 GValue *value = (GValue *) p->data;
1047 size_t l2;
1048
1049 strcpy( q, vips_value_get_ref_string( value, &l2 ) );
1050 q += l2;
1051 strcpy( q, "\n" );
1052 q += 1;
1053 }
1054
1055 g_assert( (size_t) (q - all) == length );
1056
1057 return( all );
1058 }
1059
1060 gint64
1061 vips__seek_no_error( int fd, gint64 pos, int whence )
1062 {
1063 gint64 new_pos;
1064
1065 #ifdef G_OS_WIN32
1066 new_pos = _lseeki64( fd, pos, whence );
1067 #else /*!G_OS_WIN32*/
1068 /* On error, eg. opening a directory and seeking to the end, lseek()
1069 * on linux seems to return 9223372036854775807 ((1 << 63) - 1)
1070 * rather than (off_t) -1 for reasons I don't understand.
1071 */
1072 new_pos = lseek( fd, pos, whence );
1073 #endif /*G_OS_WIN32*/
1074
1075 return( new_pos );
1076 }
1077
1078 /* Need our own seek(), since lseek() on win32 can't do long files.
1079 */
1080 gint64
1081 vips__seek( int fd, gint64 pos, int whence )
1082 {
1083 gint64 new_pos;
1084
1085 if( (new_pos = vips__seek_no_error( fd, pos, whence )) == -1 ) {
1086 vips_error_system( errno, "vips__seek",
1087 "%s", _( "unable to seek" ) );
1088 return( -1 );
1089 }
1090
1091 return( new_pos );
1092 }
1093
1094 /* Need our own ftruncate(), since ftruncate() on win32 can't do long files.
1095
1096 DANGER ... this moves the file pointer to the end of file on win32,
1097 but not on *nix; don't make any assumptions about the file pointer
1098 position after calling this
1099
1100 */
1101 int
1102 vips__ftruncate( int fd, gint64 pos )
1103 {
1104 #ifdef G_OS_WIN32
1105 {
1106 HANDLE hFile = (HANDLE) _get_osfhandle( fd );
1107
1108 if( vips__seek( fd, pos, SEEK_SET ) == -1 )
1109 return( -1 );
1110 if( !SetEndOfFile( hFile ) ) {
1111 vips_error_system( GetLastError(), "vips__ftruncate",
1112 "%s", _( "unable to truncate" ) );
1113 return( -1 );
1114 }
1115 }
1116 #else /*!G_OS_WIN32*/
1117 if( ftruncate( fd, pos ) ) {
1118 vips_error_system( errno, "vips__ftruncate",
1119 "%s", _( "unable to truncate" ) );
1120 return( -1 );
1121 }
1122 #endif /*G_OS_WIN32*/
1123
1124 return( 0 );
1125 }
1126
1127 /* TRUE if file exists. True for directories as well.
1128 */
1129 gboolean
1130 vips_existsf( const char *name, ... )
1131 {
1132 va_list ap;
1133 char *path;
1134 gboolean result;
1135
1136 va_start( ap, name );
1137 path = g_strdup_vprintf( name, ap );
1138 va_end( ap );
1139
1140 result = g_file_test( path, G_FILE_TEST_EXISTS );
1141
1142 g_free( path );
1143
1144 return( result );
1145 }
1146
1147 /* TRUE if file exists and is a directory.
1148 */
1149 gboolean
1150 vips_isdirf( const char *name, ... )
1151 {
1152 va_list ap;
1153 char *path;
1154 gboolean result;
1155
1156 va_start( ap, name );
1157 path = g_strdup_vprintf( name, ap );
1158 va_end( ap );
1159
1160 result = g_file_test( path, G_FILE_TEST_IS_DIR );
1161
1162 g_free( path );
1163
1164 return( result );
1165 }
1166
1167 /* Make a directory.
1168 */
1169 int
1170 vips_mkdirf( const char *name, ... )
1171 {
1172 va_list ap;
1173 char *path;
1174
1175 va_start( ap, name );
1176 path = g_strdup_vprintf( name, ap );
1177 va_end( ap );
1178
1179 if( g_mkdir( path, 0755 ) ) {
1180 vips_error( "mkdirf",
1181 _( "unable to create directory \"%s\", %s" ),
1182 path, strerror( errno ) );
1183 g_free( path );
1184 return( -1 );
1185 }
1186 g_free( path );
1187
1188 return( 0 );
1189 }
1190
1191 /* Remove a directory.
1192 */
1193 int
1194 vips_rmdirf( const char *name, ... )
1195 {
1196 va_list ap;
1197 char *path;
1198
1199 va_start( ap, name );
1200 path = g_strdup_vprintf( name, ap );
1201 va_end( ap );
1202
1203 if( g_rmdir( path ) ) {
1204 vips_error( "rmdir",
1205 _( "unable to remove directory \"%s\", %s" ),
1206 path, strerror( errno ) );
1207 g_free( path );
1208 return( -1 );
1209 }
1210 g_free( path );
1211
1212 return( 0 );
1213 }
1214
1215 /* Rename a file.
1216 */
1217 int
1218 vips_rename( const char *old_name, const char *new_name )
1219 {
1220 if( g_rename( old_name, new_name ) ) {
1221 vips_error( "rename",
1222 _( "unable to rename file \"%s\" as \"%s\", %s" ),
1223 old_name, new_name, strerror( errno ) );
1224 return( -1 );
1225 }
1226
1227 return( 0 );
1228 }
1229
1230 /* Chop off any trailing whitespace.
1231 */
1232 void
1233 vips__chomp( char *str )
1234 {
1235 char *p;
1236
1237 for( p = str + strlen( str ); p > str && isspace( p[-1] ); p-- )
1238 p[-1] = '\0';
1239 }
1240
1241 /* Break a command-line argument into tokens separated by whitespace.
1242 *
1243 * Strings can't be adjacent, so "hello world" (without quotes) is a single
1244 * string. Strings are written (with \" escaped) into @string. If the string
1245 * is larger than @size, it is silently null-terminated and truncated.
1246 *
1247 * Return NULL for end of tokens.
1248 */
1249 const char *
1250 vips__token_get( const char *p, VipsToken *token, char *string, int size )
1251 {
1252 const char *q;
1253 int ch;
1254 int n;
1255 int i;
1256
1257 /* Parse this token with p.
1258 */
1259 if( !p )
1260 return( NULL );
1261
1262 /* Skip initial whitespace.
1263 */
1264 p += strspn( p, " \t\n\r" );
1265 if( !p[0] )
1266 return( NULL );
1267
1268 switch( (ch = p[0]) ) {
1269 case '[':
1270 *token = VIPS_TOKEN_LEFT;
1271 p += 1;
1272 break;
1273
1274 case ']':
1275 *token = VIPS_TOKEN_RIGHT;
1276 p += 1;
1277 break;
1278
1279 case '=':
1280 *token = VIPS_TOKEN_EQUALS;
1281 p += 1;
1282 break;
1283
1284 case ',':
1285 *token = VIPS_TOKEN_COMMA;
1286 p += 1;
1287 break;
1288
1289 case '"':
1290 case '\'':
1291 /* Parse a quoted string. Copy up to ", interpret any \",
1292 * error if no closing ".
1293 */
1294 *token = VIPS_TOKEN_STRING;
1295
1296 do {
1297 /* Number of characters until the next quote
1298 * character or end of string.
1299 */
1300 if( (q = strchr( p + 1, ch )) )
1301 n = q - p + 1;
1302 else
1303 n = strlen( p + 1 );
1304
1305 /* How much can we copy to the buffer?
1306 */
1307 i = VIPS_MIN( n, size );
1308 vips_strncpy( string, p + 1, i );
1309
1310 /* We might have stopped at an escaped quote. If the
1311 * string was not truncated, swap the preceding
1312 * backslash for a quote.
1313 */
1314 if( p[n + 1] == ch && p[n] == '\\' && i == n )
1315 string[i - 1] = ch;
1316
1317 string += i;
1318 size -= i;
1319 p += n + 1;
1320 } while( p[0] && p[-1] == '\\' );
1321
1322 p += 1;
1323
1324 break;
1325
1326 default:
1327 /* It's an unquoted string: read up to the next non-string
1328 * character. We don't allow two strings next to each other,
1329 * so the next break must be brackets, equals, comma.
1330 */
1331 *token = VIPS_TOKEN_STRING;
1332 q = p + strcspn( p, "[]=," );
1333
1334 i = VIPS_MIN( q - p, size );
1335 vips_strncpy( string, p, i + 1 );
1336 p = q;
1337
1338 /* We remove leading whitespace, so we trim trailing
1339 * whitespace from unquoted strings too. Only if the string
1340 * hasn't been truncated.
1341 */
1342 if( i != size )
1343 while( i > 0 && isspace( string[i - 1] ) ) {
1344 string[i - 1] = '\0';
1345 i--;
1346 }
1347
1348 break;
1349 }
1350
1351 return( p );
1352 }
1353
1354 /* We expect a token.
1355 */
1356 const char *
1357 vips__token_must( const char *p, VipsToken *token,
1358 char *string, int size )
1359 {
1360 if( !(p = vips__token_get( p, token, string, size )) ) {
1361 vips_error( "get_token",
1362 "%s", _( "unexpected end of string" ) );
1363 return( NULL );
1364 }
1365
1366 return( p );
1367 }
1368
1369 /* We expect a certain token.
1370 */
1371 const char *
1372 vips__token_need( const char *p, VipsToken need_token,
1373 char *string, int size )
1374 {
1375 VipsToken token;
1376
1377 if( !(p = vips__token_must( p, &token, string, size )) )
1378 return( NULL );
1379 if( token != need_token ) {
1380 vips_error( "get_token", _( "expected %s, saw %s" ),
1381 vips_enum_nick( VIPS_TYPE_TOKEN, need_token ),
1382 vips_enum_nick( VIPS_TYPE_TOKEN, token ) );
1383 return( NULL );
1384 }
1385
1386 return( p );
1387 }
1388
1389 /* Fetch a token. If it's a string token terminated by a '[', fetch up to the
1390 * matching ']' as well, for example ".jpg[Q=90]".
1391 *
1392 * Return NULL for end of tokens.
1393 */
1394 const char *
1395 vips__token_segment( const char *p, VipsToken *token,
1396 char *string, int size )
1397 {
1398 const char *q;
1399
1400 if( !(q = vips__token_must( p, token, string, size )) )
1401 return( NULL );
1402
1403 /* If we stopped on [, read up to the matching ].
1404 */
1405 if( *token == VIPS_TOKEN_STRING &&
1406 q[0] == '[' ) {
1407 VipsToken sub_token;
1408 char sub_string[VIPS_PATH_MAX];
1409 int depth;
1410 int i;
1411
1412 depth = 0;
1413 do {
1414 if( !(q = vips__token_must( q, &sub_token,
1415 sub_string, VIPS_PATH_MAX )) )
1416 return( NULL );
1417
1418 switch( sub_token ) {
1419 case VIPS_TOKEN_LEFT:
1420 depth += 1;
1421 break;
1422
1423 case VIPS_TOKEN_RIGHT:
1424 depth -= 1;
1425 break;
1426
1427 default:
1428 break;
1429 }
1430 } while( !(sub_token == VIPS_TOKEN_RIGHT && depth == 0) );
1431
1432 i = VIPS_MIN( q - p, size );
1433 vips_strncpy( string, p, i + 1 );
1434 }
1435
1436 return( q );
1437 }
1438
1439 /* We expect a certain segment.
1440 */
1441 const char *
1442 vips__token_segment_need( const char *p, VipsToken need_token,
1443 char *string, int size )
1444 {
1445 VipsToken token;
1446
1447 if( !(p = vips__token_segment( p, &token, string, size )) )
1448 return( NULL );
1449 if( token != need_token ) {
1450 vips_error( "get_token", _( "expected %s, saw %s" ),
1451 vips_enum_nick( VIPS_TYPE_TOKEN, need_token ),
1452 vips_enum_nick( VIPS_TYPE_TOKEN, token ) );
1453 return( NULL );
1454 }
1455
1456 return( p );
1457 }
1458
1459 /* Maximum number of tokens we allow in a filename. Surely this will be
1460 * plenty.
1461 */
1462 #define MAX_TOKENS (1000)
1463
1464 /* Find the start of the right-most pair of brackets in the string.
1465 *
1466 * A string can be of the form:
1467 *
1468 * "hello world! (no really).tif[fred=12]"
1469 *
1470 * we need to be able to find the fred=12 at the end.
1471 *
1472 * We lex the whole string noting the position of each token, then, if the
1473 * final token is a right-bracket, search left for the matching left-bracket.
1474 *
1475 * This can get confused if the lefts are hidden inside another token :-( But
1476 * a fixing that would require us to write a separate right-to-left lexer,
1477 * argh.
1478 */
1479 const char *
1480 vips__find_rightmost_brackets( const char *p )
1481 {
1482 const char *start[MAX_TOKENS + 1];
1483 VipsToken tokens[MAX_TOKENS];
1484 char str[VIPS_PATH_MAX];
1485 int n, i;
1486 int nest;
1487
1488 start[0] = p;
1489 for( n = 0;
1490 n < MAX_TOKENS &&
1491 (p = vips__token_get( start[n], &tokens[n],
1492 str, VIPS_PATH_MAX ));
1493 n++, start[n] = p )
1494 ;
1495
1496 /* Too many tokens?
1497 */
1498 if( n >= MAX_TOKENS )
1499 return( NULL );
1500
1501 /* No rightmost close bracket?
1502 */
1503 if( n == 0 ||
1504 tokens[n - 1] != VIPS_TOKEN_RIGHT )
1505 return( NULL );
1506
1507 nest = 0;
1508 for( i = n - 1; i >= 0; i-- ) {
1509 if( tokens[i] == VIPS_TOKEN_RIGHT )
1510 nest += 1;
1511 else if( tokens[i] == VIPS_TOKEN_LEFT )
1512 nest -= 1;
1513
1514 if( nest == 0 )
1515 break;
1516 }
1517
1518 /* No matching left bracket?
1519 */
1520 if( nest != 0 )
1521 return( NULL );
1522
1523 /* This should be the matching left.
1524 */
1525 return( start[i] );
1526 }
1527
1528 /* Split a vips8-style filename + options.
1529 *
1530 * filename and option_string must be VIPS_PATH_MAX in length.
1531 */
1532 void
1533 vips__filename_split8( const char *name, char *filename, char *option_string )
1534 {
1535 char *p;
1536
1537 vips_strncpy( filename, name, VIPS_PATH_MAX );
1538 if( (p = (char *) vips__find_rightmost_brackets( filename )) ) {
1539 vips_strncpy( option_string, p, VIPS_PATH_MAX );
1540 *p = '\0';
1541 }
1542 else
1543 vips_strncpy( option_string, "", VIPS_PATH_MAX );
1544 }
1545
1546 /* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just
1547 * integer arithmetic for portability. A previous Nicos version using doubles
1548 * and log/log failed on x86 with rounding problems. Return 0 for not
1549 * power of two, otherwise return the position of the set bit (numbering with
1550 * bit 1 as the lsb).
1551 */
1552 int
1553 vips_ispoweroftwo( int p )
1554 {
1555 int i, n;
1556
1557 /* Count set bits. Could use a LUT, I guess.
1558 */
1559 for( i = 0, n = 0; p; i++, p >>= 1 )
1560 if( p & 1 )
1561 n++;
1562
1563 /* Should be just one set bit.
1564 */
1565 if( n == 1 )
1566 /* Return position of bit.
1567 */
1568 return( i );
1569 else
1570 return( 0 );
1571 }
1572
1573 /* Test this processor for endianness. True for SPARC order.
1574 */
1575 int
1576 vips_amiMSBfirst( void )
1577 {
1578 #if G_BYTE_ORDER == G_BIG_ENDIAN
1579 return( 1 );
1580 #elif G_BYTE_ORDER == G_LITTLE_ENDIAN
1581 return( 0 );
1582 #else
1583 #error "Byte order not recognised"
1584 #endif
1585 }
1586
1587 /* Return the tmp dir. On Windows, GetTempPath() will also check the values of
1588 * TMP, TEMP and USERPROFILE.
1589 */
1590 static const char *
1591 vips__temp_dir( void )
1592 {
1593 const char *tmpd;
1594
1595 if( !(tmpd = g_getenv( "TMPDIR" )) ) {
1596 #ifdef G_OS_WIN32
1597 static gboolean done = FALSE;
1598 static char buf[256];
1599
1600 if( !done ) {
1601 if( !GetTempPath( 256, buf ) )
1602 strcpy( buf, "C:\\temp" );
1603 }
1604 tmpd = buf;
1605 #else /*!G_OS_WIN32*/
1606 tmpd = "/tmp";
1607 #endif /*!G_OS_WIN32*/
1608 }
1609
1610 return( tmpd );
1611 }
1612
1613 /* Make a temporary file name. The format parameter is something like "%s.jpg"
1614 * and will be expanded to something like "/tmp/vips-12-34587.jpg".
1615 *
1616 * You need to free the result.
1617 */
1618 char *
1619 vips__temp_name( const char *format )
1620 {
1621 static int global_serial = 0;
1622
1623 char file[FILENAME_MAX];
1624 char file2[FILENAME_MAX];
1625 char *name;
1626
1627 int serial = g_atomic_int_add( &global_serial, 1 );
1628
1629 vips_snprintf( file, FILENAME_MAX, "vips-%d-%u",
1630 serial, g_random_int() );
1631 vips_snprintf( file2, FILENAME_MAX, format, file );
1632 name = g_build_filename( vips__temp_dir(), file2, NULL );
1633
1634 /* We could use something like g_mkstemp() to guarantee uniqueness
1635 * across processes, but the extra FS calls can be difficult for
1636 * selinux.
1637 *
1638 * g_random_int() should be safe enough -- it's seeded from time(), so
1639 * it ought not to collide often -- and on linux at least we never
1640 * actually use these filenames in the filesystem anyway.
1641 */
1642
1643 return( name );
1644 }
1645
1646 /* Strip off any of a set of old suffixes (eg. [".v", ".jpg"]), add a single
1647 * new suffix (eg. ".tif").
1648 */
1649 void
1650 vips__change_suffix( const char *name, char *out, int mx,
1651 const char *new, const char **olds, int nolds )
1652 {
1653 char *p;
1654 int i;
1655 int len;
1656
1657 /* Copy start string.
1658 */
1659 vips_strncpy( out, name, mx );
1660
1661 /* Drop all matching suffixes.
1662 */
1663 while( (p = strrchr( out, '.' )) ) {
1664 /* Found suffix - test against list of alternatives. Ignore
1665 * case.
1666 */
1667 for( i = 0; i < nolds; i++ )
1668 if( g_ascii_strcasecmp( p, olds[i] ) == 0 ) {
1669 *p = '\0';
1670 break;
1671 }
1672
1673 /* Found match? If not, break from loop.
1674 */
1675 if( *p )
1676 break;
1677 }
1678
1679 /* Add new suffix.
1680 */
1681 len = strlen( out );
1682 vips_strncpy( out + len, new, mx - len );
1683 }
1684
1685 typedef struct {
1686 const char unit;
1687 int multiplier;
1688 } Unit;
1689
1690 guint64
1691 vips__parse_size( const char *size_string )
1692 {
1693 static Unit units[] = {
1694 { 'k', 1024 },
1695 { 'm', 1024 * 1024 },
1696 { 'g', 1024 * 1024 * 1024 }
1697 };
1698
1699 guint64 size;
1700 int n;
1701 int i;
1702 char *unit;
1703
1704 /* An easy way to alloc a buffer large enough.
1705 */
1706 unit = g_strdup( size_string );
1707 n = sscanf( size_string, "%d %s", &i, unit );
1708 size = i;
1709 if( n > 1 ) {
1710 int j;
1711
1712 for( j = 0; j < VIPS_NUMBER( units ); j++ )
1713 if( tolower( unit[0] ) == units[j].unit ) {
1714 size *= units[j].multiplier;
1715 break;
1716 }
1717 }
1718 g_free( unit );
1719
1720 VIPS_DEBUG_MSG( "parse_size: parsed \"%s\" as %" G_GUINT64_FORMAT "\n",
1721 size_string, size );
1722
1723 return( size );
1724 }
1725
1726 /* Look up the const char * for an enum value.
1727 */
1728 const char *
1729 vips_enum_string( GType enm, int v )
1730 {
1731 GEnumValue *value;
1732
1733 if( !(value = g_enum_get_value( g_type_class_ref( enm ), v )) )
1734 return( "(null)" );
1735
1736 return( value->value_name );
1737 }
1738
1739 const char *
1740 vips_enum_nick( GType enm, int v )
1741 {
1742 GEnumValue *value;
1743
1744 if( !(value = g_enum_get_value( g_type_class_ref( enm ), v )) )
1745 return( "(null)" );
1746
1747 return( value->value_nick );
1748 }
1749
1750 int
1751 vips_enum_from_nick( const char *domain, GType type, const char *nick )
1752 {
1753 GTypeClass *class;
1754 GEnumClass *genum;
1755 GEnumValue *enum_value;
1756 int i;
1757 char str[1000];
1758 VipsBuf buf = VIPS_BUF_STATIC( str );
1759
1760 if( !(class = g_type_class_ref( type )) ) {
1761 vips_error( domain, "%s", _( "no such enum type" ) );
1762 return( -1 );
1763 }
1764 genum = G_ENUM_CLASS( class );
1765
1766 if( (enum_value = g_enum_get_value_by_name( genum, nick )) )
1767 return( enum_value->value );
1768 if( (enum_value = g_enum_get_value_by_nick( genum, nick )) )
1769 return( enum_value->value );
1770
1771 /* -1 since we always have a "last" member.
1772 */
1773 for( i = 0; i < genum->n_values - 1; i++ ) {
1774 if( i > 0 )
1775 vips_buf_appends( &buf, ", " );
1776 vips_buf_appends( &buf, genum->values[i].value_nick );
1777 }
1778
1779 vips_error( domain, _( "enum '%s' has no member '%s', "
1780 "should be one of: %s" ),
1781 g_type_name( type ), nick, vips_buf_all( &buf ) );
1782
1783 return( -1 );
1784 }
1785
1786 int
1787 vips_flags_from_nick( const char *domain, GType type, const char *nick )
1788 {
1789 GTypeClass *class;
1790 GFlagsClass *gflags;
1791 GFlagsValue *flags_value;
1792 int i;
1793 char str[1000];
1794 VipsBuf buf = VIPS_BUF_STATIC( str );
1795
1796 if( !(class = g_type_class_ref( type )) ) {
1797 vips_error( domain, "%s", _( "no such flag type" ) );
1798 return( -1 );
1799 }
1800 gflags = G_FLAGS_CLASS( class );
1801
1802 if( (flags_value = g_flags_get_value_by_name( gflags, nick )) )
1803 return( flags_value->value );
1804 if( (flags_value = g_flags_get_value_by_nick( gflags, nick )) )
1805 return( flags_value->value );
1806
1807 for( i = 0; i < gflags->n_values; i++ ) {
1808 if( i > 0 )
1809 vips_buf_appends( &buf, ", " );
1810 vips_buf_appends( &buf, gflags->values[i].value_nick );
1811 }
1812
1813 vips_error( domain, _( "flags '%s' has no member '%s', "
1814 "should be one of: %s" ),
1815 g_type_name( type ), nick, vips_buf_all( &buf ) );
1816
1817 return( -1 );
1818 }
1819
1820 /* Scan @buf for the first "%ns" (eg. "%12s") and substitute the
1821 * lowest-numbered one for @sub. @buf is @len bytes in size.
1822 *
1823 * If there are no %ns, use the first %s.
1824 */
1825 int
1826 vips__substitute( char *buf, size_t len, char *sub )
1827 {
1828 size_t buflen = strlen( buf );
1829 size_t sublen = strlen( sub );
1830
1831 int lowest_n;
1832 char *sub_start;
1833 char *p;
1834 char *sub_end;
1835 size_t before_len, marker_len, after_len, final_len;
1836
1837 g_assert( buflen < len );
1838
1839 lowest_n = -1;
1840 sub_start = NULL;
1841 sub_end = NULL;
1842 for( p = buf; (p = strchr( p, '%' )); p++ )
1843 if( isdigit( p[1] ) ) {
1844 char *q;
1845
1846 for( q = p + 1; isdigit( *q ); q++ )
1847 ;
1848 if( q[0] == 's' ) {
1849 int n;
1850
1851 n = atoi( p + 1 );
1852 if( lowest_n == -1 ||
1853 n < lowest_n ) {
1854 lowest_n = n;
1855 sub_start = p;
1856 sub_end = q + 1;
1857 }
1858 }
1859 }
1860
1861 if( !sub_start )
1862 for( p = buf; (p = strchr( p, '%' )); p++ )
1863 if( p[1] == 's' ) {
1864 sub_start = p;
1865 sub_end = p + 2;
1866 break;
1867 }
1868
1869 if( !sub_start )
1870 return( -1 );
1871
1872 before_len = sub_start - buf;
1873 marker_len = sub_end - sub_start;
1874 after_len = buflen - (before_len + marker_len);
1875 final_len = before_len + sublen + after_len + 1;
1876 if( final_len > len )
1877 return( -1 );
1878
1879 memmove( buf + before_len + sublen, buf + before_len + marker_len,
1880 after_len + 1 );
1881 memmove( buf + before_len, sub, sublen );
1882
1883 return( 0 );
1884 }
1885
1886 /* Absoluteize a path. Free the result with g_free().
1887 */
1888 char *
1889 vips_realpath( const char *path )
1890 {
1891 char *real;
1892
1893 /* It'd be nice to use realpath here, but sadly that won't work on
1894 * linux systems with grsec, since it works by opening /proc/self/fd.
1895 */
1896
1897 if( !g_path_is_absolute( path ) ) {
1898 char *cwd;
1899
1900 cwd = g_get_current_dir();
1901 real = g_build_filename( cwd, path, NULL );
1902 g_free( cwd );
1903 }
1904 else
1905 real = g_strdup( path );
1906
1907 return( real );
1908 }
1909
1910 /* A very simple random number generator. See:
1911 * http://isthe.com/chongo/tech/comp/fnv/#FNV-source
1912 */
1913 guint32
1914 vips__random( guint32 seed )
1915 {
1916 return( 1103515245u * seed + 12345 );
1917 }
1918
1919 guint32
1920 vips__random_add( guint32 seed, int value )
1921 {
1922 seed = ((2166136261u ^ seed) * 16777619u) ^ value;
1923
1924 return( vips__random( seed ) );
1925 }
1926
1927 static void *
1928 vips_icc_dir_once( void *null )
1929 {
1930 #ifdef G_OS_WIN32
1931 /* From glib get_windows_directory_root()
1932 */
1933 wchar_t wwindowsdir[MAX_PATH];
1934
1935 if( GetWindowsDirectoryW( wwindowsdir, G_N_ELEMENTS( wwindowsdir ) ) ) {
1936 /* Usually X:\Windows, but in terminal server environments
1937 * might be an UNC path, AFAIK.
1938 */
1939 char *windowsdir;
1940
1941 if( (windowsdir = g_utf16_to_utf8( wwindowsdir,
1942 -1, NULL, NULL, NULL)) ) {
1943 gchar *full_path;
1944
1945 full_path = g_build_filename( windowsdir,
1946 "system32", "spool", "drivers", "color", NULL );
1947 g_free( windowsdir );
1948
1949 return( (void *) full_path );
1950 }
1951 }
1952 #endif /*G_OS_WIN32*/
1953
1954 return( (void *) VIPS_ICC_DIR );
1955 }
1956
1957 const char *
1958 vips__icc_dir( void )
1959 {
1960 static GOnce once = G_ONCE_INIT;
1961
1962 return( (const char *) g_once( &once,
1963 vips_icc_dir_once, NULL ) );
1964 }
1965
1966 #ifdef G_OS_WIN32
1967 static HMODULE vips__dll = NULL;
1968 #ifdef DLL_EXPORT
1969 BOOL WINAPI
1970 DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
1971 {
1972 if( fdwReason == DLL_PROCESS_ATTACH )
1973 vips__dll = hinstDLL;
1974
1975 return( TRUE );
1976 }
1977 #endif
1978 #endif /*G_OS_WIN32*/
1979
1980 static void *
1981 vips__windows_prefix_once( void *null )
1982 {
1983 char *prefix;
1984
1985 #ifdef G_OS_WIN32
1986 prefix = g_win32_get_package_installation_directory_of_module(
1987 vips__dll );
1988 #else /*!G_OS_WIN32*/
1989 prefix = (char *) g_getenv( "VIPSHOME" );
1990 #endif /*G_OS_WIN32*/
1991
1992 return( (void *) prefix );
1993 }
1994
1995 const char *
1996 vips__windows_prefix( void )
1997 {
1998 static GOnce once = G_ONCE_INIT;
1999
2000 return( (const char *) g_once( &once,
2001 vips__windows_prefix_once, NULL ) );
2002 }
2003
2004 char *
2005 vips__get_iso8601( void )
2006 {
2007 char *date;
2008
2009 #ifdef HAVE_DATE_TIME_FORMAT_ISO8601
2010 {
2011 GDateTime *now;
2012
2013 now = g_date_time_new_now_local();
2014 date = g_date_time_format_iso8601( now );
2015 g_date_time_unref( now );
2016 }
2017 #else /*!HAVE_DATE_TIME_FORMAT_ISO8601*/
2018 {
2019 GTimeVal now;
2020
2021 g_get_current_time( &now );
2022 date = g_time_val_to_iso8601( &now );
2023 }
2024 #endif /*HAVE_DATE_TIME_FORMAT_ISO8601*/
2025
2026 return( date );
2027 }
2028
2029 /* Convert a string to a double in the ASCII locale (ie. decimal point is
2030 * ".").
2031 */
2032 int
2033 vips_strtod( const char *str, double *out )
2034 {
2035 const char *p;
2036
2037 *out = 0;
2038
2039 /* The str we fetched must contain at least 1 digit. This
2040 * helps stop us trying to convert "MATLAB" (for example) to
2041 * a number and getting zero.
2042 */
2043 for( p = str; *p; p++ )
2044 if( isdigit( *p ) )
2045 break;
2046 if( !*p )
2047 return( -1 );
2048
2049 /* This will fail for out of range numbers, like 1e343434, but
2050 * is quite happy with eg. "banana".
2051 */
2052 *out = g_ascii_strtod( str, NULL );
2053 if( errno )
2054 return( -1 );
2055
2056 return( 0 );
2057 }
2058