|  | /* | 
|  | * Utility functions. | 
|  | * | 
|  | * Copyright 2003 Dimitrie O. Paun | 
|  | * Copyright 2003 Ferenc Wagner | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
|  | */ | 
|  |  | 
|  | #include <stdarg.h> | 
|  | #include <windef.h> | 
|  | #include <winbase.h> | 
|  |  | 
|  | #include "winetest.h" | 
|  |  | 
|  | HANDLE logfile = 0; | 
|  |  | 
|  | void *xmalloc (size_t len) | 
|  | { | 
|  | void *p = malloc (len); | 
|  |  | 
|  | if (!p) report (R_FATAL, "Out of memory."); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | void *xrealloc (void *op, size_t len) | 
|  | { | 
|  | void *p = realloc (op, len); | 
|  |  | 
|  | if (len && !p) report (R_FATAL, "Out of memory."); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | char *xstrdup( const char *str ) | 
|  | { | 
|  | char *res = strdup( str ); | 
|  | if (!res) report (R_FATAL, "Out of memory."); | 
|  | return res; | 
|  | } | 
|  |  | 
|  | static char *vstrfmtmake (size_t *lenp, const char *fmt, va_list ap) | 
|  | { | 
|  | size_t size = 1000; | 
|  | char *p, *q; | 
|  | int n; | 
|  |  | 
|  | p = malloc (size); | 
|  | if (!p) return NULL; | 
|  | while (1) { | 
|  | n = vsnprintf (p, size, fmt, ap); | 
|  | if (n < 0) size *= 2;   /* Windows */ | 
|  | else if ((unsigned)n >= size) size = n+1; /* glibc */ | 
|  | else break; | 
|  | q = realloc (p, size); | 
|  | if (!q) { | 
|  | free (p); | 
|  | return NULL; | 
|  | } | 
|  | p = q; | 
|  | } | 
|  | if (lenp) *lenp = n; | 
|  | return p; | 
|  | } | 
|  |  | 
|  | char *vstrmake (size_t *lenp, va_list ap) | 
|  | { | 
|  | const char *fmt; | 
|  |  | 
|  | fmt = va_arg (ap, const char*); | 
|  | return vstrfmtmake (lenp, fmt, ap); | 
|  | } | 
|  |  | 
|  | char *strmake (size_t *lenp, ...) | 
|  | { | 
|  | va_list ap; | 
|  | char *p; | 
|  |  | 
|  | va_start (ap, lenp); | 
|  | p = vstrmake (lenp, ap); | 
|  | if (!p) report (R_FATAL, "Out of memory."); | 
|  | va_end (ap); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | void xprintf (const char *fmt, ...) | 
|  | { | 
|  | va_list ap; | 
|  | size_t size; | 
|  | DWORD written; | 
|  | char *buffer, *head; | 
|  |  | 
|  | va_start (ap, fmt); | 
|  | buffer = vstrfmtmake (&size, fmt, ap); | 
|  | head = buffer; | 
|  | va_end (ap); | 
|  | while (size) { | 
|  | if (!WriteFile( logfile, head, size, &written, NULL )) | 
|  | report (R_FATAL, "Can't write logs: %u", GetLastError()); | 
|  | head += written; | 
|  | size -= written; | 
|  | } | 
|  | free (buffer); | 
|  | } | 
|  |  | 
|  | int | 
|  | goodtagchar (char c) | 
|  | { | 
|  | return (('a'<=c && c<='z') || | 
|  | ('A'<=c && c<='Z') || | 
|  | ('0'<=c && c<='9') || | 
|  | c=='-' || c=='.'); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | findbadtagchar (const char *tag) | 
|  | { | 
|  | while (*tag) | 
|  | if (goodtagchar (*tag)) tag++; | 
|  | else return tag; | 
|  | return NULL; | 
|  | } |