1 /*
2  * Copyright (c) 2002-2013 the xdvik development team
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef UTIL_H_
24 #define UTIL_H_
25 
26 #include <stdio.h>
27 #include "xdvi-config.h"
28 #include "version.h"
29 #include "kpathsea/c-stat.h"
30 #include "kpathsea/hash.h"
31 #include "kpathsea/tex-file.h"
32 
33 #if HAVE_POLL
34 # include <poll.h>
35 # define XIO_IN POLLIN
36 # define XIO_OUT POLLOUT
37 #else
38 # if HAVE_SYS_SELECT_H
39 #  include <sys/select.h>
40 # else
41 #  if HAVE_SELECT_H
42 #   include <select.h>
43 #  endif
44 # endif
45 # define XIO_IN 1
46 # define XIO_OUT 2
47 #endif
48 
49 #include "events.h" /* for child proc stuff */
50 
51 FILE *try_fopen(const char *fname, const char *mode);
52 FILE *try_fdopen(int fd, const char *mode);
53 int try_open(const char *fname, int flags);
54 int try_open_mode(const char *fname, int flags, mode_t mode);
55 
56 extern int xdvi_temp_fd(char **tempfilename);
57 extern void xdvi_assert(const char *version,
58 			const char *filename,
59 			int lineno,
60 			Boolean condition,
61 			const char *fmt,
62 			...);
63 
64 typedef void (*child_exited_proc)(int status, struct xchild *this);
65 
66 extern void handle_child_exit(int status, struct xchild *this);
67 extern char *read_child_error(int fd, void *data);
68 extern Boolean fork_process(const char *file, Boolean redirect_stdout,
69 			    const char *dirname,
70 			    childProcT exit_proc, void *data,
71 			    char *const argv[]);
72 extern void prep_fd(int fd, wide_bool noblock);
73 
74 struct bitmap; /* forward declaration */
75 extern void alloc_bitmap(struct bitmap *);
76 extern void clear_bitmap(struct bitmap *);
77 extern void fill_bitmap(struct bitmap *);
78 extern void order_reverse_bitmap(struct bitmap *);
79 
80 extern char *my_realpath(const char *path, char *real);
81 #ifdef HAVE_REALPATH
82 #include <limits.h>
83 # define REALPATH realpath
84 #else
85 # define REALPATH my_realpath
86 #endif
87 
88 char *expand_homedir(const char *path);
89 void set_dvi_name_expand(const char *new_filename);
90 void set_dvi_name(char *new_filename);
91 FILE *XFOPEN(const char *path, const char *mode);
92 
93 
94 #ifndef HAVE_MEMICMP
95 extern int memicmp(const char *, const char *, size_t);
96 #endif
97 
98 /* NOTE: all of the following are already defined by kpathsea. */
99 /*  extern void *xmalloc(unsigned); */
100 /*  extern void *xrealloc(void *, unsigned); */
101 /*  extern char *xstrdup(const char *); */
102 /*  extern void xputenv(const char *, const char *); */
103 
104 extern char *xmemdup(const char *, size_t);
105 
106 /* like xstrdup, but only copy len characters and zero-terminate at next index (allocates len+1 characters) */
107 extern char *xstrndup(const char *str, size_t len);
108 
109 extern char *xt_strdup(const char *); /* like xstrdup, but with XtMalloc() */
110 
111 extern char *xstrcat(char *str1, const char *str2);
112 extern int xpipe(int *);
113 extern void close_a_file(void);
114 extern unsigned long get_bytes(FILE *, int);
115 extern long get_lbytes(FILE *, int);
116 
117 extern void xdvi_exit(int);
118 extern void do_abort(void);
119 
120 /* various levels of warning/error messages */
121 extern void xdvi_info(const char *fmt, ...);
122 extern void xdvi_warning(const char *fmt, ...);
123 extern void xdvi_error(const char *fmt, ...);
124 extern void xdvi_fatal(const char *fmt, ...);
125 extern void xdvi_abort(const char *fmt, ...);
126 
127 extern Boolean pointerlocate(int *, int *);
128 extern unsigned long parse_debugging_string(const char *arg);
129 extern unsigned long parse_debugging_option(const char *ptr);
130 
131 extern int get_avg_font_width(XFontStruct *font);
132 extern char **split_line(const char *line, char sep, size_t begin, size_t end, size_t *ret_items);
133 extern char *find_file(const char *filename, struct stat *statbuf, kpse_file_format_type pathinfo);
134 extern char **src_format_arguments(char **argv, const char *filename, int lineno, int colno);
135 
136 /*
137   hashtable wrapper functions, mostly used by dvi-draw.c to
138   map filenames to integers. This uses the hashtable implementation
139   from kpathsea, which is reasonably fast.
140 */
141 
142 /*
143   We use this dummy wrapper stuct, which we cast to void *, to get integer
144   values into/from the hashtable (natively, kpahtsea only supports string
145   values).
146 */
147 struct str_int_hash_item {
148     int value;
149 };
150 
151 
152 typedef hash_table_type hashTableT; /* from kpathsea */
153 extern Boolean find_str_int_hash(hashTableT *hashtable, const char *key, size_t *val);
154 extern void put_str_int_hash(hashTableT *hashtable, const char *key, size_t val);
155 
156 #if FREETYPE || PS
157 
158 /*
159  *	AVL tree structures.
160  */
161 
162 #define	AVL_COMMON							\
163 	const char	*key;		/* key */			\
164 	int		key_len;	/* length of key */		\
165 	int		bal;		/* AVL balancing information */	\
166 	struct avl	*left;						\
167 	struct avl	*right
168 
169 struct avl {		/* generic data structure */
170 	AVL_COMMON;
171 };
172 
173 extern struct avl *avladd(const char *, size_t, struct avl **, size_t);
174 
175 #endif /* FREETYPE || PS */
176 
177 
178 extern Boolean copy_file(const char *from, const char *to);
179 extern Boolean copy_fp(FILE *in, FILE *out);
180 
181 extern const char *get_text_encoding(void);
182 extern char *iconv_convert_string(const char *from_enc, const char *to_enc, const char *str);
183 
184 extern void xdvi_bell(void);
185 
186 /* Various error reporting macros.
187    The reasons why these are macros are:
188    - possibility to use __FILE__, __LINE__
189    - (more importantly:) gcc can't do type checking on generic vararg
190      macros, but does so for the printf() functions.
191 */
192 
193 /*
194  *	Print an informative message to stdout,
195  *	unless the resource `hush_stdout' is set.
196  */
197 #define XDVI_INFO(X) do {					\
198 	fprintf(stdout, "%s: Info: ", globals.program_name);	\
199 	fflush(stdout); /* in case following goes to stderr accidentally ... */ \
200 	fprintf X;						\
201 	fprintf(stdout, "\n");					\
202 	fflush(stdout); /* to make sure it doesn't get intermingled with stderr */ \
203 } while(0)
204 
205 
206 /*
207  *	Print a warning message to stderr.
208  *	This can't be shut off by `hush_stdout'.
209  */
210 #define XDVI_WARNING(X) do {					\
211 	fprintf(stderr, "%s: Warning: ", globals.program_name);	\
212 	fprintf X;						\
213 	fprintf(stderr, "\n");					\
214 } while(0)
215 
216 /*
217  *	Print an un-typed message to stderr, without starting a newline.
218  *	This can't be shut off by `hush_stdout'.
219  */
220 #define XDVI_MSG(X) do {					\
221 	fprintf(stderr, "%s: ", globals.program_name);		\
222 	fprintf X;						\
223 } while(0)
224 
225 
226 /*
227  *	Print an error message to stderr.
228  *	This can't be shut off by `hush_stdout'.
229  */
230 #define XDVI_ERROR(X) do {					\
231 	fprintf(stderr, "%s: Error: ", globals.program_name);	\
232 	fprintf X;						\
233 	fprintf(stderr, "\n");					\
234 } while(0)
235 
236 /*
237  *	Print an error message and quit. Use this only with extreme care,
238  *	if recovery is really impossible!
239  */
240 #define XDVI_FATAL(X) do {						\
241 	fprintf(stderr, "%s: Fatal error: ", globals.program_name);	\
242 	fprintf X;							\
243 	fprintf(stderr, "\n");						\
244 	xdvi_exit(EXIT_FAILURE);					\
245 } while(0)
246 
247 /*
248  *	Print an error message and abort. Use this instead of assertions
249  *	if you want to give a more informative message.
250  */
251 #define XDVI_ABORT(X) do {					\
252 	fprintf(stderr, "%s %s: %s:%d: Shouldn't happen: ",	\
253 			globals.program_name,			\
254 			XDVI_VERSION_INFO,			\
255 			__FILE__, __LINE__);			\
256 	fprintf X;						\
257 	fprintf(stderr, "\n");					\
258 	do_abort();						\
259 } while(0)
260 
261 #endif /* UTIL_H_ */
262