1 /* Declarations for some basic util functions.
2  */
3 
4 /*
5 
6     Copyright (C) 1991-2003 The National Gallery
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program 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
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 
22  */
23 
24 /*
25 
26     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
27 
28 */
29 
30 /* chartype strings. Useful with break_token().
31  */
32 #define NUMERIC "0123456789"
33 #define WHITESPACE " \t\r\b\n"
34 
35 /* Like IM_NEW() etc, but set ip's error buffer.
36  */
37 #define INEW(IM,A) ((A *)imalloc((IM),sizeof(A)))
38 #define IARRAY(IM,N,T) ((T *)imalloc((IM),(N) * sizeof(T)))
39 
40 /* No nulls! Handy for printf() %s
41  */
42 #define NN( S ) ((S)?(S):"(null)")
43 
44 #define UNREF( X ) do { \
45 	if( X ) { \
46 		g_object_unref( G_OBJECT( X ) ); \
47 		(X) = NULL; \
48 	} \
49 } while( 0 )
50 
51 #define GOG_UNREF( X ) do { \
52 	if( X ) { \
53 		gog_object_clear_parent( GOG_OBJECT( X ) ); \
54 		g_object_unref( G_OBJECT( X ) ); \
55 		(X) = NULL; \
56 	} \
57 } while( 0 )
58 
59 #define FREESID( SID, OBJ ) do { \
60 	if( (SID) && (OBJ) ) { \
61 		g_signal_handler_disconnect( (OBJ), (SID) ); \
62 		(SID) = 0; \
63 	} \
64 } while( 0 )
65 
66 /* Swap two pointers.
67  */
68 #define SWAPP( A, B ) { \
69 	void *swapp_t; \
70  	\
71 	swapp_t = (A); \
72 	(A) = (B); \
73 	(B) = swapp_t; \
74 }
75 
76 void vips_buf_appendi( VipsBuf *buf, IMAGE *im );
77 gboolean vips_buf_appendsc( VipsBuf *buf, gboolean quote, const char *str );
78 
79 gboolean set_prop( xmlNode *xnode, const char *name, const char *fmt, ... )
80 	__attribute__((format(printf, 3, 4)));
81 gboolean set_sprop( xmlNode *xnode, const char *name, const char *value );
82 gboolean set_iprop( xmlNode *xnode, const char *name, int value );
83 gboolean set_dprop( xmlNode *xnode, const char *name, double value );
84 gboolean set_slprop( xmlNode *xnode, const char *name, GSList *labels );
85 gboolean set_dlprop( xmlNode *xnode, const char *name, double *values, int n );
86 
87 gboolean get_sprop( xmlNode *xnode, const char *name, char *buf, int sz );
88 gboolean get_spropb( xmlNode *xnode, const char *name, VipsBuf *buf );
89 gboolean get_iprop( xmlNode *xnode, const char *name, int *out );
90 gboolean get_dprop( xmlNode *xnode, const char *name, double *out );
91 gboolean get_bprop( xmlNode *xnode, const char *name, gboolean *out );
92 gboolean get_slprop( xmlNode *xnode, const char *name, GSList **out );
93 gboolean get_dlprop( xmlNode *xnode, const char *name, double **out );
94 
95 xmlNode *get_node( xmlNode *base, const char *name );
96 
97 Rect *rect_dup( Rect *init );
98 void *rect_free( Rect *rect );
99 
100 /* Like GFunc, but return a value.
101  */
102 typedef gpointer (*SListMapFn)( gpointer, gpointer );
103 typedef gpointer (*SListMap2Fn)( gpointer, gpointer, gpointer );
104 typedef gpointer (*SListMap3Fn)( gpointer, gpointer, gpointer, gpointer );
105 typedef gpointer (*SListMap4Fn)( gpointer, gpointer, gpointer, gpointer,
106 	gpointer );
107 typedef gpointer (*SListMap5Fn)( gpointer, gpointer, gpointer, gpointer,
108 	gpointer, gpointer );
109 typedef gpointer (*SListFoldFn)( gpointer, gpointer, gpointer );
110 typedef gpointer (*SListFold2Fn)( gpointer, gpointer, gpointer, gpointer );
111 
112 /* Like foreach, but allow abandon.
113  */
114 void *slist_map( GSList *list, SListMapFn fn, gpointer a );
115 void *slist_map2( GSList *list, SListMap2Fn fn, gpointer a, gpointer b );
116 void *slist_map3( GSList *list,
117 	SListMap3Fn fn, gpointer a, gpointer b, gpointer c );
118 void *slist_map4( GSList *list,
119 	SListMap4Fn fn, gpointer a, gpointer b, gpointer c, gpointer d );
120 void *slist_map5( GSList *list,
121 	SListMap5Fn fn, gpointer a, gpointer b, gpointer c, gpointer d,
122 	gpointer e );
123 void *slist_map_rev( GSList *list, SListMapFn fn, gpointer a );
124 void *slist_map2_rev( GSList *list,
125 	SListMap2Fn fn, gpointer a, gpointer b );
126 void *slist_map3_rev( GSList *list,
127 	SListMap3Fn fn, void *a, void *b, void *c );
128 void *map_equal( void *a, void *b );
129 gboolean slist_equal( GSList *l1, GSList *l2 );
130 void *slist_fold( GSList *list, void *start, SListFoldFn fn, void *a );
131 void *slist_fold2( GSList *list,
132 	void *start, SListFold2Fn fn, void *a, void *b );
133 void slist_free_all( GSList *list );
134 GSList *slist_remove_all( GSList *list, gpointer data );
135 
136 /* An slist, which tracks the end of the list, for fast append.
137  */
138 typedef struct _Queue {
139 	GSList *list;
140 	GSList *tail;
141 	int length;
142 } Queue;
143 
144 Queue *queue_new( void );
145 
146 /* All we need for now.
147  */
148 void *queue_head( Queue *queue );
149 void queue_add( Queue *queue, void *data );
150 gboolean queue_remove( Queue *q, void *data );
151 int queue_length( Queue *q );
152 
153 extern VipsBuf error_top_buf;
154 extern VipsBuf error_sub_buf;
155 
156 void error( const char *fmt, ... )
157 	__attribute__((noreturn, format(printf, 1, 2)));
158 void error_block( void );		/* Block updates to error_string */
159 void error_unblock( void );
160 void error_clear( void );
161 void error_top( const char *fmt, ... )
162 	__attribute__((format(printf, 1, 2)));
163 void error_sub( const char *fmt, ... )
164 	__attribute__((format(printf, 1, 2)));
165 void error_vips( void );
166 void error_vips_all( void );
167 const char *error_get_top( void );
168 const char *error_get_sub( void );
169 
170 gboolean is_postfix( const char *a, const char *b );
171 gboolean is_prefix( const char *a, const char *b );
172 gboolean is_caseprefix( const char *a, const char *b );
173 gboolean is_casepostfix( const char *a, const char *b );
174 const char *findrightmost( const char *a, const char *b );
175 char *my_strcasestr( const char *haystack, const char *needle );
176 void change_suffix( const char *name, char *out,
177 	const char *new, const char **olds, int nolds );
178 
179 char *my_strccpy( char *output, const char *input );
180 char *my_strecpy( char *output, const char *input, gboolean quote );
181 const char *my_strrspn( const char *p, const char *spn );
182 
183 char *trim_nonalpha( char *text );
184 char *trim_white( char *text );
185 
186 void *get_element( REGION *ireg, int x, int y, int b );
187 
188 const char *decode_bandfmt( int f );
189 const char *decode_type( int t );
190 
191 void get_image_info( VipsBuf *buf, const char *name );
192 
193 void expand_variables( const char *in, char *out );
194 void nativeize_path( char *buf );
195 void absoluteize_path( char *path );
196 void canonicalize_path( char *path );
197 const char *get_vipshome( const char *argv0 );
198 
199 typedef void *(*callv_string_fn)( const char *name, void *a, void *b, void *c );
200 
201 void *callv_string( callv_string_fn fn,
202 	const char *name, void *a, void *b, void *c );
203 void *callv_stringva( callv_string_fn fn,
204 	const char *name, va_list ap, void *a, void *b, void *c );
205 void *callv_stringf( callv_string_fn fn, const char *fmt, ... )
206 	__attribute__((format(printf, 2, 3)));
207 
208 void *callv_string_filename( callv_string_fn fn,
209 	const char *filename, void *a, void *b, void *c );
210 void *callv_string_filenameva( callv_string_fn fn,
211 	const char *name, va_list ap, void *a, void *b, void *c );
212 void *callv_string_filenamef( callv_string_fn fn, const char *fmt, ... )
213 	__attribute__((format(printf, 2, 3)));
214 
215 typedef int (*calli_string_fn)( const char *name, void *a, void *b, void *c );
216 
217 int calli_string( calli_string_fn fn,
218 	const char *name, void *a, void *b, void *c );
219 int calli_stringva( calli_string_fn fn,
220 	const char *name, va_list ap, void *a, void *b, void *c );
221 int calli_stringf( calli_string_fn fn, const char *fmt, ... )
222 	__attribute__((format(printf, 2, 3)));
223 
224 int calli_string_filename( calli_string_fn fn,
225 	const char *filename, void *a, void *b, void *c );
226 int calli_string_filenameva( calli_string_fn fn,
227 	const char *name, va_list ap, void *a, void *b, void *c );
228 int calli_string_filenamef( calli_string_fn fn, const char *fmt, ... )
229 	__attribute__((format(printf, 2, 3)));
230 
231 char *f2utf8( const char *filename );
232 
233 char *im_strdupn( const char *str );
234 void setenvf( const char *name, const char *fmt, ... )
235 	__attribute__((format(printf, 2, 3)));
236 gboolean existsf( const char *name, ... )
237 	__attribute__((format(printf, 1, 2)));
238 gboolean isdir( const char *filename, ... )
239 	__attribute__((format(printf, 1, 2)));
240 time_t mtime( const char *filename, ... )
241 	__attribute__((format(printf, 1, 2)));
242 gboolean mkdirf( const char *name, ... )
243 	__attribute__((format(printf, 1, 2)));
244 int systemf( const char *fmt, ... )
245 	__attribute__((format(printf, 1, 2)));
246 FILE *popenf( const char *fmt, const char *mode, ... )
247 	__attribute__((format(printf, 1, 3)));
248 gboolean touchf( const char *fmt, ... )
249 	__attribute__((format(printf, 1, 2)));
250 int unlinkf( const char *fmt, ... )
251 	__attribute__((format(printf, 1, 2)));
252 gboolean is_absolute( const char *fname );
253 gboolean is_valid_filename( const char *name );
254 
255 /* Text IO to/from files. Track the filename too, to help error messages.
256  */
257 typedef struct _iOpenFile {
258 	FILE *fp;
259 	char *fname;		/* File we were passed to make this open_file */
260 	char *fname_real;	/* File we opened (maybe after search) */
261 	int last_errno;		/* On error, last value for errno */
262 	gboolean read;		/* True for open read, false for open write */
263 } iOpenFile;
264 
265 void ifile_close( iOpenFile *of );
266 iOpenFile *ifile_open_read( const char *name, ... )
267 	__attribute__((format(printf, 1, 2)));
268 iOpenFile *ifile_open_read_stdin();
269 iOpenFile *ifile_open_write( const char *name, ... )
270 	__attribute__((format(printf, 1, 2)));
271 gboolean ifile_write( iOpenFile *of, const char *fmt, ... )
272 	__attribute__((format(printf, 2, 3)));
273 gboolean ifile_write_var( iOpenFile *of, const char *name, const char *value );
274 char *ifile_read( iOpenFile *of );
275 char *ifile_read_buffer( iOpenFile *of, char *buffer, size_t len );
276 int ifile_getc( iOpenFile *of );
277 
278 double directory_size( const char *dirname );
279 
280 char *escape_percent( const char *in, char *out, int len );
281 char *escape_markup( const char *in, char *out, int len );
282 char *escape_mode( const char *in, char *out, int len );
283 char *break_token( char *str, const char *brk );
284 const char *rpt( char ch, int n );
285 const char *spc( int n );
286 void number_to_string( int n, char *buf );
287 
288 double find_space( const char *name );
289 gboolean temp_name( char *name, const char *ext );
290 int findmaxmin( IMAGE *in,
291 	int left, int top, int width, int height, double *min, double *max );
292 
293 gboolean char_to_bool( char *str, void *out );
294 char *bool_to_char( gboolean b );
295 
296 void increment_name( char *buf );
297 void increment_filename( char *filename );
298 
299 int extract_first_line( char *buf, char *str, int len );
300 
301 void name_from_filename( const char *in, char *out );
302 
303 void util_check_all_destroyed( void );
304 
305 void *imalloc( IMAGE *im, size_t len );
306 
307 GSList *recent_add( GSList *recent, const char *filename );
308 GSList *recent_load( const char *filename );
309 void recent_free( GSList *recent );
310 void recent_save( GSList *recent, const char *filename );
311 
312 const char *get_savedir( void );
313 
314 void **slist_to_array( GSList *list );
315 int array_len( void **array );
316