2 * Copyright (C) 2000, Matias Atria
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 static char *const messages[] = {
36 _G("Houston, we have a problem"),
37 _G("3.. 2.. 1.. BOOM!"),
42 #define NMSGS (sizeof(messages) / sizeof(char *))
44 static FILE *logfile = NULL;
45 static int _mdvi_log_level;
47 int mdvi_set_logfile(const char *filename);
48 int mdvi_set_logstream(FILE *file);
49 int mdvi_set_loglevel(int level);
51 static void vputlog(int level, const char *head, const char *format, va_list ap)
53 if(logfile != NULL && _mdvi_log_level >= level) {
55 fprintf(logfile, "%s: ", head);
56 vfprintf(logfile, format, ap);
60 int mdvi_set_logfile(const char *filename)
64 if(filename && (f = fopen(filename, "w")) == NULL)
66 if(logfile != NULL && !isatty(fileno(logfile))) {
75 int mdvi_set_logstream(FILE *file)
77 if(logfile && !isatty(fileno(logfile))) {
85 int mdvi_set_loglevel(int level)
87 int old = _mdvi_log_level;
89 _mdvi_log_level = level;
94 Uint32 _mdvi_debug_mask = 0;
96 void __debug(int mask, const char *format, ...)
100 va_start(ap, format);
101 if(_mdvi_debug_mask & mask) {
102 if(!DEBUGGING(SILENT)) {
103 fprintf(stderr, "Debug: ");
104 vfprintf(stderr, format, ap);
108 /* let's be portable */
110 va_start(ap, format);
112 vputlog(LOG_DEBUG, "Debug", format, ap);
118 void mdvi_message(const char *format, ...)
122 va_start(ap, format);
123 if(_mdvi_log_level >= LOG_INFO) {
124 fprintf(stderr, "%s: ", program_name);
125 vfprintf(stderr, format, ap);
128 va_start(ap, format);
131 vputlog(LOG_INFO, NULL, format, ap);
135 void mdvi_crash(const char *format, ...)
139 va_start(ap, format);
140 fprintf(stderr, "%s: %s: ",
142 gettext(messages[(int)time(NULL) % NMSGS]));
143 vfprintf(stderr, format, ap);
145 /* let's be portable */
147 va_start(ap, format);
149 vputlog(LOG_ERROR, _("Crashing"), format, ap);
154 void mdvi_error(const char *format, ...)
158 va_start(ap, format);
159 fprintf(stderr, _("%s: Error: "), program_name);
160 vfprintf(stderr, format, ap);
162 /* let's be portable */
164 va_start(ap, format);
166 vputlog(LOG_ERROR, _("Error"), format, ap);
170 void mdvi_warning(const char *format, ...)
174 va_start(ap, format);
175 fprintf(stderr, _("%s: Warning: "), program_name);
176 vfprintf(stderr, format, ap);
178 /* let's be portable */
180 va_start(ap, format);
182 vputlog(LOG_WARN, _("Warning"), format, ap);
186 void mdvi_fatal(const char *format, ...)
190 va_start(ap, format);
191 fprintf(stderr, _("%s: Fatal: "), program_name);
192 vfprintf(stderr, format, ap);
194 /* let's be portable */
196 va_start(ap, format);
198 vputlog(LOG_ERROR, _("Fatal"), format, ap);
207 void *mdvi_malloc(size_t nelems)
209 void *ptr = malloc(nelems);
212 mdvi_fatal(_("out of memory allocating %u bytes\n"),
217 void *mdvi_realloc(void *data, size_t newsize)
222 mdvi_crash(_("attempted to reallocate with zero size\n"));
223 ptr = realloc(data, newsize);
225 mdvi_fatal(_("failed to reallocate %u bytes\n"), (unsigned)newsize);
229 void *mdvi_calloc(size_t nmemb, size_t size)
234 mdvi_crash(_("attempted to callocate 0 members\n"));
236 mdvi_crash(_("attempted to callocate %u members with size 0\n"),
238 ptr = calloc(nmemb, size);
240 mdvi_fatal(_("failed to allocate %ux%u bytes\n"),
241 (unsigned)nmemb, (unsigned)size);
245 void mdvi_free(void *ptr)
248 mdvi_crash(_("attempted to free NULL pointer\n"));
252 char *mdvi_strdup(const char *string)
257 length = strlen(string) + 1;
258 ptr = (char *)mdvi_malloc(length);
259 memcpy(ptr, string, length);
263 /* `to' should have room for length+1 bytes */
264 char *mdvi_strncpy(char *to, const char *from, size_t length)
266 strncpy(to, from, length);
271 char *mdvi_strndup(const char *string, size_t length)
279 ptr = (char *)mdvi_malloc(n + 1);
280 memcpy(ptr, string, n);
284 void *mdvi_memdup(const void *data, size_t length)
286 void *ptr = mdvi_malloc(length);
288 memcpy(ptr, data, length);
292 char *mdvi_strrstr (const char *haystack, const char *needle)
299 needle_len = strlen (needle);
300 haystack_len = strlen (haystack);
305 if (haystack_len < needle_len)
306 return (char *)haystack;
308 p = haystack + haystack_len - needle_len;
309 while (p >= haystack) {
310 for (i = 0; i < needle_len; i++)
311 if (p[i] != needle[i])
323 char *mdvi_build_path_from_cwd (const char *path)
327 size_t buf_size = 512;
330 buf = mdvi_realloc (buf, buf_size);
331 if ((ptr = getcwd (buf, buf_size)) == NULL && errno == ERANGE) {
339 buf = mdvi_realloc (buf, strlen (buf) + strlen (path) + 2);
341 strncat (buf, path, strlen (path));
346 double unit2pix_factor(const char *spec)
351 static const char *units = "incmmmmtptpcddccspbpftydcs";
355 for(p = spec; *p >= '0' && *p <= '9'; p++)
356 val = 10.0 * val + (double)(*p - '0');
360 while(*p && *p >= '0' && *p <= '9') {
361 val += (*p++ - '0') * factor;
362 factor = factor * 0.1;
366 for(q = units; *q; q += 2) {
367 if(p[0] == q[0] && p[1] == q[1])
370 switch((int)(q - units)) {
371 /*in*/ case 0: factor = 1.0; break;
372 /*cm*/ case 2: factor = 1.0 / 2.54; break;
373 /*mm*/ case 4: factor = 1.0 / 25.4; break;
374 /*mt*/ case 6: factor = 1.0 / 0.0254; break;
375 /*pt*/ case 8: factor = 1.0 / 72.27; break;
376 /*pc*/ case 10: factor = 12.0 / 72.27; break;
377 /*dd*/ case 12: factor = (1238.0 / 1157.0) / 72.27; break;
378 /*cc*/ case 14: factor = 12 * (1238.0 / 1157.0) / 72.27; break;
379 /*sp*/ case 16: factor = 1.0 / (72.27 * 65536); break;
380 /*bp*/ case 18: factor = 1.0 / 72.0; break;
381 /*ft*/ case 20: factor = 12.0; break;
382 /*yd*/ case 22: factor = 36.0; break;
383 /*cs*/ case 24: factor = 1.0 / 72000.0; break;
384 default: factor = 1.0;
389 int unit2pix(int dpi, const char *spec)
391 double factor = unit2pix_factor(spec);
393 return (int)(factor * dpi + 0.5);
396 Ulong get_mtime(int fd)
400 if(fstat(fd, &st) == 0)
401 return (Ulong)st.st_mtime;
405 char *xstradd(char *dest, size_t *size, size_t n, const char *src, size_t m)
410 dest = mdvi_realloc(dest, n + m + 1);
413 memcpy(dest + n, src, m);
418 char *getword(char *string, const char *delim, char **end)
423 /* skip leading delimiters */
424 for(ptr = string; *ptr && strchr(delim, *ptr); ptr++);
429 /* skip non-delimiters */
430 while(*ptr && !strchr(delim, *ptr))
436 char *getstring(char *string, const char *delim, char **end)
442 /* skip leading delimiters */
443 for(ptr = string; *ptr && strchr(delim, *ptr); ptr++);
447 quoted = (*ptr == '"');
449 for(word = ++ptr; *ptr && *ptr != '"'; ptr++);
451 for(word = ptr; *ptr && !strchr(delim, *ptr); ptr++);
456 static long pow2(size_t n)
458 long x = 8; /* don't bother allocating less than this */
465 void dstring_init(Dstring *dstr)
472 int dstring_append(Dstring *dstr, const char *string, int len)
475 len = strlen(string);
477 if(dstr->length + len >= dstr->size) {
478 dstr->size = pow2(dstr->length + len + 1);
479 dstr->data = mdvi_realloc(dstr->data, dstr->size);
481 memcpy(dstr->data + dstr->length, string, len);
483 dstr->data[dstr->length] = 0;
484 } else if(dstr->size == 0) {
485 ASSERT(dstr->data == NULL);
487 dstr->data = mdvi_malloc(8);
494 int dstring_copy(Dstring *dstr, int pos, const char *string, int len)
498 len = strlen(string);
500 if(pos + len >= dstr->length) {
502 return dstring_append(dstr, string, len);
504 memcpy(dstr->data + pos, string, len);
509 int dstring_insert(Dstring *dstr, int pos, const char *string, int len)
512 if(pos == dstr->length)
513 return dstring_append(dstr, string, len);
515 len = strlen(string);
517 if(dstr->length + len >= dstr->size) {
518 dstr->size = pow2(dstr->length + len + 1);
519 dstr->data = mdvi_realloc(dstr->data, dstr->size);
522 memmove(dstr->data + pos, dstr->data + pos + len, len);
524 memcpy(dstr->data + pos, string, len);
526 dstr->data[dstr->length] = 0;
531 int dstring_new(Dstring *dstr, const char *string, int len)
534 len = strlen(string);
536 dstr->size = pow2(len + 1);
537 dstr->data = mdvi_malloc(dstr->size * len);
538 memcpy(dstr->data, string, len);
544 void dstring_reset(Dstring *dstr)
547 mdvi_free(dstr->data);