Fix:Core:Added missing file to glib Makefile, force linking of g_utf8_strlen
[navit-package] / navit / util.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
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.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <glib.h>
21 #include <ctype.h>
22 #include <stdarg.h>
23 #include "util.h"
24
25 void
26 strtoupper(char *dest, const char *src)
27 {
28         while (*src)
29                 *dest++=toupper(*src++);
30         *dest='\0';
31 }
32
33 void
34 strtolower(char *dest, const char *src)
35 {
36         while (*src)
37                 *dest++=tolower(*src++);
38         *dest='\0';
39 }
40
41
42 static void
43 hash_callback(gpointer key, gpointer value, gpointer user_data)
44 {
45         GList **l=user_data;
46         *l=g_list_prepend(*l, value);
47 }
48
49 GList *
50 g_hash_to_list(GHashTable *h)
51 {
52         GList *ret=NULL;
53         g_hash_table_foreach(h, hash_callback, &ret);
54
55         return ret;
56 }
57
58 gchar *
59 g_strconcat_printf(gchar *buffer, gchar *fmt, ...)
60 {
61         gchar *str,*ret;
62         va_list ap;
63
64         va_start(ap, fmt);
65         str=g_strdup_vprintf(fmt, ap);
66         va_end(ap);
67         if (! buffer)
68                 return str;
69         ret=g_strconcat(buffer, str, NULL);
70         g_free(buffer);
71         g_free(str);
72         return ret;
73 }
74
75 #ifndef HAVE_GLIB
76 int g_utf8_strlen_force_link(gchar *buffer, int max);
77 int
78 g_utf8_strlen_force_link(gchar *buffer, int max)
79 {
80         return g_utf8_strlen(buffer, max);
81 }
82 #endif
83
84 #if defined(_WIN32) || defined(__CEGCC__)
85 #include <windows.h>
86 #include <stdio.h>
87 char *stristr(const char *String, const char *Pattern)
88 {
89       char *pptr, *sptr, *start;
90
91       for (start = (char *)String; *start != (int)NULL; start++)
92       {
93             /* find start of pattern in string */
94             for ( ; ((*start!=(int)NULL) && (toupper(*start) != toupper(*Pattern))); start++)
95                   ;
96             if ((int)NULL == *start)
97                   return NULL;
98
99             pptr = (char *)Pattern;
100             sptr = (char *)start;
101
102             while (toupper(*sptr) == toupper(*pptr))
103             {
104                   sptr++;
105                   pptr++;
106
107                   /* if end of pattern then pattern was found */
108
109                   if ((int)NULL == *pptr)
110                         return (start);
111             }
112       }
113       return NULL;
114 }
115
116 #ifndef SIZE_MAX
117 # define SIZE_MAX ((size_t) -1)
118 #endif
119 #ifndef SSIZE_MAX
120 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
121 #endif
122 #if !HAVE_FLOCKFILE
123 # undef flockfile
124 # define flockfile(x) ((void) 0)
125 #endif
126 #if !HAVE_FUNLOCKFILE
127 # undef funlockfile
128 # define funlockfile(x) ((void) 0)
129 #endif
130
131 /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
132 #ifndef EOVERFLOW
133 # define EOVERFLOW E2BIG
134 #endif
135
136 /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
137    NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
138    NULL), pointing to *N characters of space.  It is realloc'ed as
139    necessary.  Returns the number of characters read (not including
140    the null terminator), or -1 on error or EOF.  */
141
142 ssize_t
143 getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
144 {
145   ssize_t result;
146   size_t cur_len = 0;
147
148   if (lineptr == NULL || n == NULL || fp == NULL)
149     {
150       return -1;
151     }
152
153   flockfile (fp);
154
155   if (*lineptr == NULL || *n == 0)
156     {
157       *n = 120;
158       *lineptr = (char *) realloc (*lineptr, *n);
159       if (*lineptr == NULL)
160         {
161           result = -1;
162           goto unlock_return;
163         }
164     }
165
166   for (;;)
167     {
168       int i;
169
170       i = getc (fp);
171       if (i == EOF)
172         {
173           result = -1;
174           break;
175         }
176
177       /* Make enough space for len+1 (for final NUL) bytes.  */
178       if (cur_len + 1 >= *n)
179         {
180           size_t needed_max =
181             SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
182           size_t needed = 2 * *n + 1;   /* Be generous. */
183           char *new_lineptr;
184
185           if (needed_max < needed)
186             needed = needed_max;
187           if (cur_len + 1 >= needed)
188             {
189               result = -1;
190               goto unlock_return;
191             }
192
193           new_lineptr = (char *) realloc (*lineptr, needed);
194           if (new_lineptr == NULL)
195             {
196               result = -1;
197               goto unlock_return;
198             }
199
200           *lineptr = new_lineptr;
201           *n = needed;
202         }
203
204       (*lineptr)[cur_len] = i;
205       cur_len++;
206
207       if (i == delimiter)
208         break;
209     }
210   (*lineptr)[cur_len] = '\0';
211   result = cur_len ? cur_len : result;
212
213  unlock_return:
214   funlockfile (fp); /* doesn't set errno */
215
216   return result;
217 }
218
219 ssize_t
220 getline (char **lineptr, size_t *n, FILE *stream)
221 {
222   return getdelim (lineptr, n, '\n', stream);
223 }
224
225 #if defined(_UNICODE)
226 wchar_t* newSysString(const char *toconvert)
227 {
228         int newstrlen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toconvert, -1, 0, 0);
229         wchar_t *newstring = g_new(wchar_t,newstrlen);
230         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toconvert, -1, newstring, newstrlen) ;
231         return newstring;
232 }
233 #else
234 char * newSysString(const char *toconvert)
235 {
236         return g_strdup(toconvert);
237 }
238 #endif
239 #endif