Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org>
  3.  * Copyright 2004-2007 James Bursa <bursa@users.sourceforge.net>
  4.  * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
  5.  * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
  6.  * Copyright 2004 John Tytgat <joty@netsurf-browser.org>
  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 <http://www.gnu.org/licenses/>.
  21.  */
  22.  
  23. #include <assert.h>
  24. #include <ctype.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <strings.h>
  29. #include <sys/stat.h>
  30. #include <sys/types.h>
  31. #include <sys/time.h>
  32. #include <regex.h>
  33. #include <time.h>
  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.  
  279.         /* LOG(("WALLCLOCK IS HERE")); */
  280.        
  281.         if (gettimeofday(&tv, NULL) == -1)
  282.                 {LOG(("And -1"));return 0;}
  283.  
  284.     /* LOG(("And time")); */
  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
  434.