Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * Copyright 2007 Rob Kendrick 
3
 * Copyright 2004-2007 James Bursa 
4
 * Copyright 2003 Phil Mellor 
5
 * Copyright 2003 John M Bell 
6
 * Copyright 2004 John Tytgat 
7
 *
8
 * This file is part of NetSurf, http://www.netsurf-browser.org/
9
 *
10
 * NetSurf is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; version 2 of the License.
13
 *
14
 * NetSurf is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program.  If not, see .
21
 */
22
 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
 
35
#include "utils/config.h"
36
#include "utils/messages.h"
37
#include "utils/utf8.h"
38
#include "utils/utils.h"
39
#include "utils/log.h"
40
 
41
void *
42
ns_realloc(void *ptr, size_t size, void *pw)
43
{
44
	(void)pw;
45
 
46
	if (ptr == NULL)
47
		return size > 0 ? malloc(size) : NULL;
48
	if (size == 0) {
49
		free(ptr);
50
		return NULL;
51
	}
52
	return realloc(ptr, size);
53
}
54
 
55
char * strip(char * const s)
56
{
57
	size_t i;
58
	for (i = strlen(s);
59
			i != 0 && (s[i - 1] == ' ' || s[i - 1] == '\n' ||
60
			s[i - 1] == '\r' || s[i - 1] == '\t');
61
			i--)
62
		;
63
	s[i] = 0;
64
	return s + strspn(s, " \t\r\n");
65
}
66
 
67
int whitespace(const char * str)
68
{
69
	unsigned int i;
70
	for (i = 0; i < strlen(str); i++)
71
		if (!isspace(str[i]))
72
			return 0;
73
	return 1;
74
}
75
 
76
/**
77
 * returns a string without its underscores
78
 * \param replacespace true to insert a space where there was an underscore
79
 */
80
 
81
char *remove_underscores(const char *s, bool replacespace)
82
{
83
	size_t i, ii, len;
84
	char *ret;
85
	len = strlen(s);
86
	ret = malloc(len + 1);
87
	if (ret == NULL)
88
		return NULL;
89
	for (i = 0, ii = 0; i < len; i++) {
90
		if (s[i] != '_')
91
			ret[ii++] = s[i];
92
		else if (replacespace)
93
			ret[ii++] = ' ';
94
	}
95
	ret[ii] = '\0';
96
	return ret;
97
}
98
 
99
/**
100
 * Replace consecutive whitespace with a single space.
101
 *
102
 * \param  s  source string
103
 * \return  heap allocated result, or 0 on memory exhaustion
104
 */
105
 
106
char * squash_whitespace(const char *s)
107
{
108
	char *c = malloc(strlen(s) + 1);
109
	int i = 0, j = 0;
110
	if (!c)
111
		return 0;
112
	do {
113
		if (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' ||
114
				s[i] == '\t') {
115
			c[j++] = ' ';
116
			while (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' ||
117
					s[i] == '\t')
118
				i++;
119
		}
120
		c[j++] = s[i++];
121
	} while (s[i - 1] != 0);
122
	return c;
123
}
124
 
125
 
126
/**
127
 * Converts NUL terminated UTF-8 encoded string s containing zero or more
128
 * spaces (char 32) or TABs (char 9) to non-breaking spaces
129
 * (0xC2 + 0xA0 in UTF-8 encoding).
130
 *
131
 * Caller needs to free() result.  Returns NULL in case of error.  No
132
 * checking is done on validness of the UTF-8 input string.
133
 */
134
char *cnv_space2nbsp(const char *s)
135
{
136
	const char *srcP;
137
	char *d, *d0;
138
	unsigned int numNBS;
139
	/* Convert space & TAB into non breaking space character (0xA0) */
140
	for (numNBS = 0, srcP = (const char *)s; *srcP != '\0'; ++srcP)
141
		if (*srcP == ' ' || *srcP == '\t')
142
			++numNBS;
143
	if ((d = (char *)malloc((srcP - s) + numNBS + 1)) == NULL)
144
		return NULL;
145
	for (d0 = d, srcP = (const char *)s; *srcP != '\0'; ++srcP) {
146
		if (*srcP == ' ' || *srcP == '\t') {
147
			*d0++ = 0xC2;
148
			*d0++ = 0xA0;
149
		} else
150
			*d0++ = *srcP;
151
	}
152
	*d0 = '\0';
153
	return d;
154
}
155
 
156
/**
157
 * Check if a directory exists.
158
 */
159
 
160
bool is_dir(const char *path)
161
{
162
	struct stat s;
163
 
164
	if (stat(path, &s))
165
		return false;
166
 
167
	return S_ISDIR(s.st_mode) ? true : false;
168
}
169
 
170
 
171
/**
172
 * Compile a regular expression, handling errors.
173
 *
174
 * Parameters as for regcomp(), see man regex.
175
 */
176
 
177
void regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
178
{
179
	int r;
180
	r = regcomp(preg, regex, cflags);
181
	if (r) {
182
		char errbuf[200];
183
		regerror(r, preg, errbuf, sizeof errbuf);
184
		fprintf(stderr, "Failed to compile regexp '%s'\n", regex);
185
		die(errbuf);
186
	}
187
}
188
 
189
/** We can have a fairly good estimate of how long the buffer needs to
190
  * be.  The unsigned long can store a value representing a maximum size
191
  * of around 4 GB.  Therefore the greatest space required is to
192
  * represent 1023MB.  Currently that would be represented as "1023MB" so 12
193
  * including a null terminator.
194
  * Ideally we would be able to know this value for sure, in the mean
195
  * time the following should suffice.
196
 **/
197
 
198
#define BYTESIZE_BUFFER_SIZE 20
199
 
200
/**
201
  * Does a simple conversion which assumes the user speaks English.  The buffer
202
  * returned is one of three static ones so may change each time this call is
203
  * made.  Don't store the buffer for later use.  It's done this way for
204
  * convenience and to fight possible memory leaks, it is not necessarily pretty.
205
 **/
206
 
207
char *human_friendly_bytesize(unsigned long bsize) {
208
	static char buffer1[BYTESIZE_BUFFER_SIZE];
209
	static char buffer2[BYTESIZE_BUFFER_SIZE];
210
	static char buffer3[BYTESIZE_BUFFER_SIZE];
211
	static char *curbuffer = buffer3;
212
	enum {bytes, kilobytes, megabytes, gigabytes} unit = bytes;
213
	static char units[][7] = {"Bytes", "kBytes", "MBytes", "GBytes"};
214
 
215
	float bytesize = (float)bsize;
216
 
217
	if (curbuffer == buffer1)
218
		curbuffer = buffer2;
219
	else if (curbuffer == buffer2)
220
		curbuffer = buffer3;
221
	else
222
		curbuffer = buffer1;
223
 
224
	if (bytesize > 1024) {
225
		bytesize /= 1024;
226
		unit = kilobytes;
227
	}
228
 
229
	if (bytesize > 1024) {
230
		bytesize /= 1024;
231
		unit = megabytes;
232
	}
233
 
234
	if (bytesize > 1024) {
235
		bytesize /= 1024;
236
		unit = gigabytes;
237
	}
238
 
239
	sprintf(curbuffer, "%3.2f%s", bytesize, messages_get(units[unit]));
240
 
241
	return curbuffer;
242
}
243
 
244
/**
245
 * Create an RFC 1123 compliant date string from a Unix timestamp
246
 *
247
 * \param t The timestamp to consider
248
 * \return Pointer to buffer containing string - invalidated by next call.
249
 */
250
const char *rfc1123_date(time_t t)
251
{
252
	static char ret[30];
253
 
254
	struct tm *tm = gmtime(&t);
255
	const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
256
		*months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
257
				"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
258
 
259
	snprintf(ret, sizeof ret, "%s, %02d %s %d %02d:%02d:%02d GMT",
260
			days[tm->tm_wday], tm->tm_mday, months[tm->tm_mon],
261
			tm->tm_year + 1900, tm->tm_hour, tm->tm_min,
262
			tm->tm_sec);
263
 
264
	return ret;
265
}
266
 
267
/**
268
 * Returns a number of centiseconds, that increases in real time, for the
269
 * purposes of measuring how long something takes in wall-clock terms.  It uses
270
 * gettimeofday() for this.  Should the call to gettimeofday() fail, it returns
271
 * zero.
272
 *
273
 * \return number of centiseconds that increases monotonically
274
 */
275
unsigned int wallclock(void)
276
{
277
	struct timeval tv;
278
 
5043 ashmew2 279
	/* LOG(("WALLCLOCK IS HERE")); */
3584 sourcerer 280
 
281
	if (gettimeofday(&tv, NULL) == -1)
282
		{LOG(("And -1"));return 0;}
283
 
5043 ashmew2 284
    /* LOG(("And time")); */
3584 sourcerer 285
	return ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
286
}
287
 
288
#ifndef HAVE_STRCASESTR
289
 
290
/**
291
 * Case insensitive strstr implementation
292
 *
293
 * \param haystack String to search in
294
 * \param needle String to look for
295
 * \return Pointer to start of found substring, or NULL if not found
296
 */
297
char *strcasestr(const char *haystack, const char *needle)
298
{
299
	size_t needle_len = strlen(needle);
300
	const char * last_start = haystack + (strlen(haystack) - needle_len);
301
 
302
	while (haystack <= last_start) {
303
		if (strncasecmp(haystack, needle, needle_len) == 0)
304
			return (char *)haystack;
305
		haystack++;
306
	}
307
 
308
	return NULL;
309
}
310
 
311
#endif
312
 
313
#ifndef HAVE_STRNDUP
314
 
315
/**
316
 * Duplicate up to n characters of a string.
317
 */
318
 
319
char *strndup(const char *s, size_t n)
320
{
321
	size_t len;
322
	char *s2;
323
 
324
	for (len = 0; len != n && s[len]; len++)
325
		continue;
326
 
327
	s2 = malloc(len + 1);
328
	if (!s2)
329
		return 0;
330
 
331
	memcpy(s2, s, len);
332
	s2[len] = 0;
333
	return s2;
334
}
335
 
336
#endif
337
 
338
#ifndef HAVE_STRCHRNUL
339
 
340
/**
341
 *  Find the first occurrence of C in S or the final NUL byte.
342
 */
343
char *strchrnul (const char *s, int c_in)
344
{
345
	const unsigned char *us = (const unsigned char *) s;
346
 
347
	while (*us != c_in && *us != '\0')
348
		us++;
349
 
350
	return (void *) us;
351
}
352
 
353
#endif
354
 
355
#ifndef HAVE_UTSNAME
356
#include "utils/utsname.h"
357
 
358
int uname(struct utsname *buf) {
359
	strcpy(buf->sysname,"windows");
360
	strcpy(buf->nodename,"nodename");
361
	strcpy(buf->release,"release");
362
	strcpy(buf->version,"version");
363
	strcpy(buf->machine,"pc");
364
 
365
	return 0;
366
}
367
#endif
368
 
369
#ifndef HAVE_REALPATH
370
char *realpath(const char *path, char *resolved_path)
371
{
372
	char *ret;
373
	if (resolved_path == NULL) {
374
		ret=strdup(path);
375
	} else {
376
		ret = resolved_path;
377
		strcpy(resolved_path, path);
378
	}
379
	return ret;
380
}
381
 
382
#ifndef HAVE_INETATON
383
 
384
 
385
int inet_aton(const char *cp, struct in_addr *inp)
386
{
387
	unsigned int b1, b2, b3, b4;
388
	unsigned char c;
389
 
390
	if (strspn(cp, "0123456789.") < strlen(cp))
391
		return 0;
392
 
393
	if (sscanf(cp, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
394
		return 0;
395
 
396
	if ((b1 > 255) || (b2 > 255) || (b3 > 255) || (b4 > 255))
397
		return 0;
398
 
399
	inp->s_addr = b4 << 24 | b3 << 16 | b2 << 8 | b1;
400
 
401
	return 1;
402
}
403
 
404
#endif
405
 
406
#ifndef HAVE_INETPTON
407
 
408
int inet_pton(int af, const char *src, void *dst)
409
{
410
	int ret;
411
 
412
	if (af == AF_INET) {
413
		ret = inet_aton(src, dst);
414
	}
415
#if !defined(NO_IPV6)
416
	else if (af == AF_INET6) {
417
		/* TODO: implement v6 address support */
418
		ret = -1;
419
		errno = EAFNOSUPPORT;
420
	}
421
#endif
422
	else {
423
		ret = -1;
424
		errno = EAFNOSUPPORT;
425
	}
426
 
427
	return ret;
428
}
429
 
430
#endif
431
 
432
 
433
#endif