Changeset a35b458 in mainline for uspace/lib/c/generic/str.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
r3061bc1 ra35b458 85 85 if (*offset + 1 > size) 86 86 return 0; 87 87 88 88 /* First byte read from string */ 89 89 uint8_t b0 = (uint8_t) str[(*offset)++]; 90 90 91 91 /* Determine code length */ 92 92 93 93 unsigned int b0_bits; /* Data bits in first byte */ 94 94 unsigned int cbytes; /* Number of continuation bytes */ 95 95 96 96 if ((b0 & 0x80) == 0) { 97 97 /* 0xxxxxxx (Plain ASCII) */ … … 114 114 return U_SPECIAL; 115 115 } 116 116 117 117 if (*offset + cbytes > size) 118 118 return U_SPECIAL; 119 119 120 120 wchar_t ch = b0 & LO_MASK_8(b0_bits); 121 121 122 122 /* Decode continuation bytes */ 123 123 while (cbytes > 0) { 124 124 uint8_t b = (uint8_t) str[(*offset)++]; 125 125 126 126 /* Must be 10xxxxxx */ 127 127 if ((b & 0xc0) != 0x80) 128 128 return U_SPECIAL; 129 129 130 130 /* Shift data bits to ch */ 131 131 ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS)); 132 132 cbytes--; 133 133 } 134 134 135 135 return ch; 136 136 } … … 155 155 if (*offset == 0) 156 156 return 0; 157 157 158 158 size_t processed = 0; 159 159 /* Continue while continuation bytes found */ 160 160 while (*offset > 0 && processed < 4) { 161 161 uint8_t b = (uint8_t) str[--(*offset)]; 162 162 163 163 if (processed == 0 && (b & 0x80) == 0) { 164 164 /* 0xxxxxxx (Plain ASCII) */ … … 200 200 if (*offset >= size) 201 201 return EOVERFLOW; 202 202 203 203 if (!chr_check(ch)) 204 204 return EINVAL; 205 205 206 206 /* Unsigned version of ch (bit operations should only be done 207 207 on unsigned types). */ 208 208 uint32_t cc = (uint32_t) ch; 209 209 210 210 /* Determine how many continuation bytes are needed */ 211 211 212 212 unsigned int b0_bits; /* Data bits in first byte */ 213 213 unsigned int cbytes; /* Number of continuation bytes */ 214 214 215 215 if ((cc & ~LO_MASK_32(7)) == 0) { 216 216 b0_bits = 7; … … 229 229 return EINVAL; 230 230 } 231 231 232 232 /* Check for available space in buffer */ 233 233 if (*offset + cbytes >= size) 234 234 return EOVERFLOW; 235 235 236 236 /* Encode continuation bytes */ 237 237 unsigned int i; … … 240 240 cc = cc >> CONT_BITS; 241 241 } 242 242 243 243 /* Encode first byte */ 244 244 str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1); 245 245 246 246 /* Advance offset */ 247 247 *offset += cbytes + 1; 248 248 249 249 return EOK; 250 250 } … … 263 263 { 264 264 size_t size = 0; 265 265 266 266 while (*str++ != 0) 267 267 size++; 268 268 269 269 return size; 270 270 } … … 302 302 size_t len = 0; 303 303 size_t offset = 0; 304 304 305 305 while (len < max_len) { 306 306 if (str_decode(str, &offset, STR_NO_LIMIT) == 0) 307 307 break; 308 308 309 309 len++; 310 310 } 311 311 312 312 return offset; 313 313 } … … 327 327 { 328 328 size_t size = 0; 329 329 330 330 while ((*str++ != 0) && (size < max_size)) 331 331 size++; 332 332 333 333 return size; 334 334 } … … 379 379 size_t len = 0; 380 380 size_t offset = 0; 381 381 382 382 while (str_decode(str, &offset, STR_NO_LIMIT) != 0) 383 383 len++; 384 384 385 385 return len; 386 386 } … … 396 396 { 397 397 size_t len = 0; 398 398 399 399 while (*wstr++ != 0) 400 400 len++; 401 401 402 402 return len; 403 403 } … … 415 415 size_t len = 0; 416 416 size_t offset = 0; 417 417 418 418 while (str_decode(str, &offset, size) != 0) 419 419 len++; 420 420 421 421 return len; 422 422 } … … 435 435 size_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); 436 436 size_t offset = 0; 437 437 438 438 while ((offset < limit) && (*str++ != 0)) { 439 439 len++; 440 440 offset += sizeof(wchar_t); 441 441 } 442 442 443 443 return len; 444 444 } … … 464 464 size_t offset = 0; 465 465 wchar_t ch; 466 466 467 467 while ((ch = str_decode(str, &offset, STR_NO_LIMIT)) != 0) 468 468 width += chr_width(ch); 469 469 470 470 return width; 471 471 } … … 480 480 if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127)) 481 481 return true; 482 482 483 483 return false; 484 484 } … … 493 493 if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111)) 494 494 return true; 495 495 496 496 return false; 497 497 } … … 666 666 wchar_t c1 = 0; 667 667 wchar_t c2 = 0; 668 668 669 669 size_t off1 = 0; 670 670 size_t off2 = 0; 671 671 672 672 size_t len = 0; 673 673 … … 710 710 wchar_t c1 = 0; 711 711 wchar_t c2 = 0; 712 712 713 713 size_t off1 = 0; 714 714 size_t off2 = 0; … … 717 717 c1 = str_decode(s, &off1, STR_NO_LIMIT); 718 718 c2 = str_decode(p, &off2, STR_NO_LIMIT); 719 719 720 720 if (c2 == 0) 721 721 return true; … … 723 723 if (c1 != c2) 724 724 return false; 725 725 726 726 if (c1 == 0) 727 727 break; … … 747 747 /* There must be space for a null terminator in the buffer. */ 748 748 assert(size > 0); 749 749 750 750 size_t src_off = 0; 751 751 size_t dest_off = 0; 752 752 753 753 wchar_t ch; 754 754 while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { … … 756 756 break; 757 757 } 758 758 759 759 dest[dest_off] = '\0'; 760 760 } … … 780 780 /* There must be space for a null terminator in the buffer. */ 781 781 assert(size > 0); 782 782 783 783 size_t src_off = 0; 784 784 size_t dest_off = 0; 785 785 786 786 wchar_t ch; 787 787 while ((ch = str_decode(src, &src_off, n)) != 0) { … … 789 789 break; 790 790 } 791 791 792 792 dest[dest_off] = '\0'; 793 793 } … … 811 811 if (dstr_size >= size) 812 812 return; 813 813 814 814 str_cpy(dest + dstr_size, size - dstr_size, src); 815 815 } … … 896 896 /* There must be space for a null terminator in the buffer. */ 897 897 assert(size > 0); 898 898 899 899 src_idx = 0; 900 900 dest_off = 0; … … 971 971 972 972 assert(dlen > 0); 973 973 974 974 while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) { 975 975 if (c > 0x10000) { … … 1109 1109 { 1110 1110 size_t len = str_length(str); 1111 1111 1112 1112 wchar_t *wstr = calloc(len+1, sizeof(wchar_t)); 1113 1113 if (wstr == NULL) 1114 1114 return NULL; 1115 1115 1116 1116 str_to_wstr(wstr, len + 1, str); 1117 1117 return wstr; … … 1130 1130 size_t off = 0; 1131 1131 size_t last = 0; 1132 1132 1133 1133 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 1134 1134 if (acc == ch) … … 1136 1136 last = off; 1137 1137 } 1138 1138 1139 1139 return NULL; 1140 1140 } … … 1207 1207 size_t last = 0; 1208 1208 const char *res = NULL; 1209 1209 1210 1210 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 1211 1211 if (acc == ch) … … 1213 1213 last = off; 1214 1214 } 1215 1215 1216 1216 return (char *) res; 1217 1217 } … … 1234 1234 { 1235 1235 size_t len = wstr_length(str); 1236 1236 1237 1237 if ((pos > len) || (pos + 1 > max_pos)) 1238 1238 return false; 1239 1239 1240 1240 size_t i; 1241 1241 for (i = len; i + 1 > pos; i--) 1242 1242 str[i + 1] = str[i]; 1243 1243 1244 1244 str[pos] = ch; 1245 1245 1246 1246 return true; 1247 1247 } … … 1262 1262 { 1263 1263 size_t len = wstr_length(str); 1264 1264 1265 1265 if (pos >= len) 1266 1266 return false; 1267 1267 1268 1268 size_t i; 1269 1269 for (i = pos + 1; i <= len; i++) 1270 1270 str[i - 1] = str[i]; 1271 1271 1272 1272 return true; 1273 1273 } … … 1296 1296 if (dest == NULL) 1297 1297 return (char *) NULL; 1298 1298 1299 1299 str_cpy(dest, size, src); 1300 1300 return dest; … … 1326 1326 if (size > n) 1327 1327 size = n; 1328 1328 1329 1329 char *dest = (char *) malloc(size + 1); 1330 1330 if (dest == NULL) 1331 1331 return (char *) NULL; 1332 1332 1333 1333 str_ncpy(dest, size + 1, src, size); 1334 1334 return dest; … … 1353 1353 if (!s) 1354 1354 return NULL; 1355 1355 1356 1356 size_t len = str_size(s); 1357 1357 size_t cur; … … 1398 1398 assert(neg != NULL); 1399 1399 assert(result != NULL); 1400 1400 1401 1401 *neg = false; 1402 1402 const char *str = nptr; 1403 1403 1404 1404 /* Ignore leading whitespace */ 1405 1405 while (isspace(*str)) 1406 1406 str++; 1407 1407 1408 1408 if (*str == '-') { 1409 1409 *neg = true; … … 1411 1411 } else if (*str == '+') 1412 1412 str++; 1413 1413 1414 1414 if (base == 0) { 1415 1415 /* Decode base if not specified */ 1416 1416 base = 10; 1417 1417 1418 1418 if (*str == '0') { 1419 1419 base = 8; 1420 1420 str++; 1421 1421 1422 1422 switch (*str) { 1423 1423 case 'b': … … 1454 1454 } 1455 1455 } 1456 1456 1457 1457 *result = 0; 1458 1458 const char *startstr = str; 1459 1459 1460 1460 while (*str != 0) { 1461 1461 unsigned int digit; 1462 1462 1463 1463 if ((*str >= 'a') && (*str <= 'z')) 1464 1464 digit = *str - 'a' + 10; … … 1469 1469 else 1470 1470 break; 1471 1471 1472 1472 if (digit >= base) 1473 1473 break; 1474 1474 1475 1475 uint64_t prev = *result; 1476 1476 *result = (*result) * base + digit; 1477 1477 1478 1478 if (*result < prev) { 1479 1479 /* Overflow */ … … 1481 1481 return EOVERFLOW; 1482 1482 } 1483 1483 1484 1484 str++; 1485 1485 } 1486 1486 1487 1487 if (str == startstr) { 1488 1488 /* … … 1492 1492 str = nptr; 1493 1493 } 1494 1494 1495 1495 *endptr = (char *) str; 1496 1496 1497 1497 if (str == nptr) 1498 1498 return EINVAL; 1499 1499 1500 1500 return EOK; 1501 1501 } … … 1517 1517 { 1518 1518 assert(result != NULL); 1519 1519 1520 1520 bool neg; 1521 1521 char *lendptr; 1522 1522 uint64_t res; 1523 1523 errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res); 1524 1524 1525 1525 if (endptr != NULL) 1526 1526 *endptr = (char *) lendptr; 1527 1527 1528 1528 if (ret != EOK) 1529 1529 return ret; 1530 1530 1531 1531 /* Do not allow negative values */ 1532 1532 if (neg) 1533 1533 return EINVAL; 1534 1534 1535 1535 /* Check whether we are at the end of 1536 1536 the string in strict mode */ 1537 1537 if ((strict) && (*lendptr != 0)) 1538 1538 return EINVAL; 1539 1539 1540 1540 /* Check for overflow */ 1541 1541 uint8_t _res = (uint8_t) res; 1542 1542 if (_res != res) 1543 1543 return EOVERFLOW; 1544 1544 1545 1545 *result = _res; 1546 1546 1547 1547 return EOK; 1548 1548 } … … 1564 1564 { 1565 1565 assert(result != NULL); 1566 1566 1567 1567 bool neg; 1568 1568 char *lendptr; 1569 1569 uint64_t res; 1570 1570 errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res); 1571 1571 1572 1572 if (endptr != NULL) 1573 1573 *endptr = (char *) lendptr; 1574 1574 1575 1575 if (ret != EOK) 1576 1576 return ret; 1577 1577 1578 1578 /* Do not allow negative values */ 1579 1579 if (neg) 1580 1580 return EINVAL; 1581 1581 1582 1582 /* Check whether we are at the end of 1583 1583 the string in strict mode */ 1584 1584 if ((strict) && (*lendptr != 0)) 1585 1585 return EINVAL; 1586 1586 1587 1587 /* Check for overflow */ 1588 1588 uint16_t _res = (uint16_t) res; 1589 1589 if (_res != res) 1590 1590 return EOVERFLOW; 1591 1591 1592 1592 *result = _res; 1593 1593 1594 1594 return EOK; 1595 1595 } … … 1611 1611 { 1612 1612 assert(result != NULL); 1613 1613 1614 1614 bool neg; 1615 1615 char *lendptr; 1616 1616 uint64_t res; 1617 1617 errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res); 1618 1618 1619 1619 if (endptr != NULL) 1620 1620 *endptr = (char *) lendptr; 1621 1621 1622 1622 if (ret != EOK) 1623 1623 return ret; 1624 1624 1625 1625 /* Do not allow negative values */ 1626 1626 if (neg) 1627 1627 return EINVAL; 1628 1628 1629 1629 /* Check whether we are at the end of 1630 1630 the string in strict mode */ 1631 1631 if ((strict) && (*lendptr != 0)) 1632 1632 return EINVAL; 1633 1633 1634 1634 /* Check for overflow */ 1635 1635 uint32_t _res = (uint32_t) res; 1636 1636 if (_res != res) 1637 1637 return EOVERFLOW; 1638 1638 1639 1639 *result = _res; 1640 1640 1641 1641 return EOK; 1642 1642 } … … 1658 1658 { 1659 1659 assert(result != NULL); 1660 1660 1661 1661 bool neg; 1662 1662 char *lendptr; 1663 1663 errno_t ret = str_uint(nptr, &lendptr, base, &neg, result); 1664 1664 1665 1665 if (endptr != NULL) 1666 1666 *endptr = (char *) lendptr; 1667 1667 1668 1668 if (ret != EOK) 1669 1669 return ret; 1670 1670 1671 1671 /* Do not allow negative values */ 1672 1672 if (neg) 1673 1673 return EINVAL; 1674 1674 1675 1675 /* Check whether we are at the end of 1676 1676 the string in strict mode */ 1677 1677 if ((strict) && (*lendptr != 0)) 1678 1678 return EINVAL; 1679 1679 1680 1680 return EOK; 1681 1681 } … … 1697 1697 { 1698 1698 assert(result != NULL); 1699 1699 1700 1700 bool neg; 1701 1701 char *lendptr; 1702 1702 uint64_t res; 1703 1703 errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res); 1704 1704 1705 1705 if (endptr != NULL) 1706 1706 *endptr = (char *) lendptr; 1707 1707 1708 1708 if (ret != EOK) 1709 1709 return ret; 1710 1710 1711 1711 /* Do not allow negative values */ 1712 1712 if (neg) 1713 1713 return EINVAL; 1714 1714 1715 1715 /* Check whether we are at the end of 1716 1716 the string in strict mode */ 1717 1717 if ((strict) && (*lendptr != 0)) 1718 1718 return EINVAL; 1719 1719 1720 1720 /* Check for overflow */ 1721 1721 size_t _res = (size_t) res; 1722 1722 if (_res != res) 1723 1723 return EOVERFLOW; 1724 1724 1725 1725 *result = _res; 1726 1726 1727 1727 return EOK; 1728 1728 }
Note:
See TracChangeset
for help on using the changeset viewer.