Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2.  
  3. int
  4. fz_is_big_endian(void)
  5. {
  6.         static const int one = 1;
  7.         return *(char*)&one == 0;
  8. }
  9.  
  10. char *
  11. fz_strsep(char **stringp, const char *delim)
  12. {
  13.         char *ret = *stringp;
  14.         if (ret == NULL) return NULL;
  15.         if ((*stringp = strpbrk(*stringp, delim)) != NULL)
  16.                 *((*stringp)++) = '\0';
  17.         return ret;
  18. }
  19.  
  20. int
  21. fz_strlcpy(char *dst, const char *src, int siz)
  22. {
  23.         register char *d = dst;
  24.         register const char *s = src;
  25.         register int n = siz;
  26.  
  27.         /* Copy as many bytes as will fit */
  28.         if (n != 0 && --n != 0) {
  29.                 do {
  30.                         if ((*d++ = *s++) == 0)
  31.                                 break;
  32.                 } while (--n != 0);
  33.         }
  34.  
  35.         /* Not enough room in dst, add NUL and traverse rest of src */
  36.         if (n == 0) {
  37.                 if (siz != 0)
  38.                         *d = '\0';              /* NUL-terminate dst */
  39.                         while (*s++)
  40.                                 ;
  41.         }
  42.  
  43.         return(s - src - 1);    /* count does not include NUL */
  44. }
  45.  
  46. int
  47. fz_strlcat(char *dst, const char *src, int siz)
  48. {
  49.         register char *d = dst;
  50.         register const char *s = src;
  51.         register int n = siz;
  52.         int dlen;
  53.  
  54.         /* Find the end of dst and adjust bytes left but don't go past end */
  55.         while (*d != '\0' && n-- != 0)
  56.                 d++;
  57.         dlen = d - dst;
  58.         n = siz - dlen;
  59.  
  60.         if (n == 0)
  61.                 return dlen + strlen(s);
  62.         while (*s != '\0') {
  63.                 if (n != 1) {
  64.                         *d++ = *s;
  65.                         n--;
  66.                 }
  67.                 s++;
  68.         }
  69.         *d = '\0';
  70.  
  71.         return dlen + (s - src);        /* count does not include NUL */
  72. }
  73.  
  74. enum
  75. {
  76.         UTFmax = 4, /* maximum bytes per rune */
  77.         Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
  78.         Runeself = 0x80, /* rune and UTF sequences are the same (<) */
  79.         Runeerror = 0xFFFD, /* decoding error in UTF */
  80.         Runemax = 0x10FFFF, /* maximum rune value */
  81. };
  82.  
  83. enum
  84. {
  85.         Bit1 = 7,
  86.         Bitx = 6,
  87.         Bit2 = 5,
  88.         Bit3 = 4,
  89.         Bit4 = 3,
  90.         Bit5 = 2,
  91.  
  92.         T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
  93.         Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
  94.         T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
  95.         T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
  96.         T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
  97.         T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */
  98.  
  99.         Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
  100.         Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
  101.         Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
  102.         Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0001 1111 1111 1111 1111 1111 */
  103.  
  104.         Maskx = (1<<Bitx)-1,    /* 0011 1111 */
  105.         Testx = Maskx ^ 0xFF,   /* 1100 0000 */
  106.  
  107.         Bad = Runeerror,
  108. };
  109.  
  110. int
  111. chartorune(int *rune, char *str)
  112. {
  113.         int c, c1, c2, c3;
  114.         long l;
  115.  
  116.         /*
  117.          * one character sequence
  118.          *      00000-0007F => T1
  119.          */
  120.         c = *(unsigned char*)str;
  121.         if(c < Tx) {
  122.                 *rune = c;
  123.                 return 1;
  124.         }
  125.  
  126.         /*
  127.          * two character sequence
  128.          *      0080-07FF => T2 Tx
  129.          */
  130.         c1 = *(unsigned char*)(str+1) ^ Tx;
  131.         if(c1 & Testx)
  132.                 goto bad;
  133.         if(c < T3) {
  134.                 if(c < T2)
  135.                         goto bad;
  136.                 l = ((c << Bitx) | c1) & Rune2;
  137.                 if(l <= Rune1)
  138.                         goto bad;
  139.                 *rune = l;
  140.                 return 2;
  141.         }
  142.  
  143.         /*
  144.          * three character sequence
  145.          *      0800-FFFF => T3 Tx Tx
  146.          */
  147.         c2 = *(unsigned char*)(str+2) ^ Tx;
  148.         if(c2 & Testx)
  149.                 goto bad;
  150.         if(c < T4) {
  151.                 l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
  152.                 if(l <= Rune2)
  153.                         goto bad;
  154.                 *rune = l;
  155.                 return 3;
  156.         }
  157.  
  158.         /*
  159.          * four character sequence (21-bit value)
  160.          *      10000-1FFFFF => T4 Tx Tx Tx
  161.          */
  162.         c3 = *(unsigned char*)(str+3) ^ Tx;
  163.         if (c3 & Testx)
  164.                 goto bad;
  165.         if (c < T5) {
  166.                 l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
  167.                 if (l <= Rune3)
  168.                         goto bad;
  169.                 *rune = l;
  170.                 return 4;
  171.         }
  172.         /*
  173.          * Support for 5-byte or longer UTF-8 would go here, but
  174.          * since we don't have that, we'll just fall through to bad.
  175.          */
  176.  
  177.         /*
  178.          * bad decoding
  179.          */
  180. bad:
  181.         *rune = Bad;
  182.         return 1;
  183. }
  184.  
  185. int
  186. runetochar(char *str, int *rune)
  187. {
  188.         /* Runes are signed, so convert to unsigned for range check. */
  189.         unsigned long c;
  190.  
  191.         /*
  192.          * one character sequence
  193.          *      00000-0007F => 00-7F
  194.          */
  195.         c = *rune;
  196.         if(c <= Rune1) {
  197.                 str[0] = c;
  198.                 return 1;
  199.         }
  200.  
  201.         /*
  202.          * two character sequence
  203.          *      0080-07FF => T2 Tx
  204.          */
  205.         if(c <= Rune2) {
  206.                 str[0] = T2 | (c >> 1*Bitx);
  207.                 str[1] = Tx | (c & Maskx);
  208.                 return 2;
  209.         }
  210.  
  211.         /*
  212.          * If the Rune is out of range, convert it to the error rune.
  213.          * Do this test here because the error rune encodes to three bytes.
  214.          * Doing it earlier would duplicate work, since an out of range
  215.          * Rune wouldn't have fit in one or two bytes.
  216.          */
  217.         if (c > Runemax)
  218.                 c = Runeerror;
  219.  
  220.         /*
  221.          * three character sequence
  222.          *      0800-FFFF => T3 Tx Tx
  223.          */
  224.         if (c <= Rune3) {
  225.                 str[0] = T3 | (c >> 2*Bitx);
  226.                 str[1] = Tx | ((c >> 1*Bitx) & Maskx);
  227.                 str[2] = Tx | (c & Maskx);
  228.                 return 3;
  229.         }
  230.  
  231.         /*
  232.          * four character sequence (21-bit value)
  233.          *      10000-1FFFFF => T4 Tx Tx Tx
  234.          */
  235.         str[0] = T4 | (c >> 3*Bitx);
  236.         str[1] = Tx | ((c >> 2*Bitx) & Maskx);
  237.         str[2] = Tx | ((c >> 1*Bitx) & Maskx);
  238.         str[3] = Tx | (c & Maskx);
  239.         return 4;
  240. }
  241.  
  242. int
  243. runelen(int c)
  244. {
  245.         char str[10];
  246.         return runetochar(str, &c);
  247. }
  248.  
  249. float fz_atof(const char *s)
  250. {
  251.         double d;
  252.  
  253.         /* The errno voodoo here checks for us reading numbers that are too
  254.          * big to fit into a double. The checks for FLT_MAX ensure that we
  255.          * don't read a number that's OK as a double and then become invalid
  256.          * as we convert to a float. */
  257.         errno = 0;
  258.         d = strtod(s, NULL);
  259.         if (errno == ERANGE || d > FLT_MAX || d < -FLT_MAX) {
  260.                 /* Return 1.0, as it's a small known value that won't cause a
  261.                  * divide by 0. */
  262.                 return 1.0;
  263.         }
  264.         return (float)d;
  265. }
  266.