Tweaks for W32
[libgcrypt.git] / src / missing-string.c
1 /* missing-string.c - missing string utilities
2  * Copyright (C) 1994, 1998, 1999, 2000, 2001, 
3  *               2003 Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include "g10lib.h"
29
30
31 #ifndef HAVE_STPCPY
32 char *
33 stpcpy(char *a,const char *b)
34 {
35     while( *b )
36         *a++ = *b++;
37     *a = 0;
38
39     return (char*)a;
40 }
41 #endif
42
43
44 #ifndef HAVE_STRCASECMP
45 int
46 strcasecmp( const char *a, const char *b )
47 {
48     for( ; *a && *b; a++, b++ ) {
49         if( *a != *b && toupper(*a) != toupper(*b) )
50             break;
51     }
52     return *(const byte*)a - *(const byte*)b;
53 }
54 #endif
55
56
57 #ifdef __MINGW32__
58 /* 
59  * Like vsprintf but provides a pointer to malloc'd storage, which
60  * must be freed by the caller (gcry_free).  Taken from libiberty as
61  * found in gcc-2.95.2 and a little bit modernized.
62  * FIXME: Write a new CRT for W32.
63  */
64 int
65 vasprintf ( char **result, const char *format, va_list args)
66 {
67   const char *p = format;
68   /* Add one to make sure that it is never zero, which might cause malloc
69      to return NULL.  */
70   int total_width = strlen (format) + 1;
71   va_list ap;
72
73   /* this is not really portable but works under Windows */
74   memcpy ( &ap, &args, sizeof (va_list));
75
76   while (*p != '\0')
77     {
78       if (*p++ == '%')
79         {
80           while (strchr ("-+ #0", *p))
81             ++p;
82           if (*p == '*')
83             {
84               ++p;
85               total_width += abs (va_arg (ap, int));
86             }
87           else
88             {
89               char *endp;  
90               total_width += strtoul (p, &endp, 10);
91               p = endp;
92             }
93           if (*p == '.')
94             {
95               ++p;
96               if (*p == '*')
97                 {
98                   ++p;
99                   total_width += abs (va_arg (ap, int));
100                 }
101               else
102                 {
103                   char *endp;
104                   total_width += strtoul (p, &endp, 10);
105                   p = endp;
106                 }
107             }
108           while (strchr ("hlL", *p))
109             ++p;
110           /* Should be big enough for any format specifier except %s
111              and floats.  */
112           total_width += 30;
113           switch (*p)
114             {
115             case 'd':
116             case 'i':
117             case 'o':
118             case 'u':
119             case 'x':
120             case 'X':
121             case 'c':
122               (void) va_arg (ap, int);
123               break;
124             case 'f':
125             case 'e':
126             case 'E':
127             case 'g':
128             case 'G':
129               (void) va_arg (ap, double);
130               /* Since an ieee double can have an exponent of 307, we'll
131                  make the buffer wide enough to cover the gross case. */
132               total_width += 307;
133             
134             case 's':
135               total_width += strlen (va_arg (ap, char *));
136               break;
137             case 'p':
138             case 'n':
139               (void) va_arg (ap, char *);
140               break;
141             }
142         }
143     }
144   *result = gcry_malloc (total_width);
145   if (*result != NULL)
146     return vsprintf (*result, format, args);
147   else
148     return 0;
149 }
150
151 #endif /*__MINGW32__*/
152