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