void IP_Address::_parse_ipv6(const String& p_string) { static const int parts_total = 8; int parts[parts_total] = {0}; int parts_count = 0; bool part_found = false; bool part_skip = false; bool part_ipv4 = false; int parts_idx = 0; for (int i=0; i<p_string.length(); i++) { CharType c = p_string[i]; if (c == ':') { if (i == 0) { continue; // next must be a ":" }; if (!part_found) { part_skip = true; parts[parts_idx++] = -1; }; part_found = false; } else if (c == '.') { part_ipv4 = true; } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { if (!part_found) { parts[parts_idx++] = i; part_found = true; ++parts_count; }; } else { ERR_EXPLAIN("Invalid character in IPv6 address: " + p_string); ERR_FAIL(); }; }; int parts_extra = 0; if (part_skip) { parts_extra = parts_total - parts_count; }; int idx = 0; for (int i=0; i<parts_idx; i++) { if (parts[i] == -1) { for (int j=0; j<parts_extra; j++) { field16[idx++] = 0; }; continue; }; if (part_ipv4 && i == parts_idx - 1) { _parse_ipv4(p_string, parts[i], (uint8_t*)&field16[idx]); // should be the last one } else { _parse_hex(p_string, parts[i], (uint8_t*)&(field16[idx++])); }; }; };
static int _tokenise_number(struct sl_pp_context *context, struct sl_pp_token_info *out) { struct lookahead_state lookahead; unsigned int eaten; unsigned int is_float = 0; unsigned int pos; int c; char number[256]; /* XXX: Remove this artifical limit. */ _lookahead_init(&lookahead, context); eaten = _parse_float(&lookahead); if (!eaten) { eaten = _parse_hex(&lookahead); if (!eaten) { eaten = _parse_oct(&lookahead); if (!eaten) { eaten = _parse_dec(&lookahead); } } } else { is_float = 1; } if (!eaten) { strcpy(context->error_msg, "expected a number"); return -1; } pos = _lookahead_tell(&lookahead); c = _lookahead_getc(&lookahead); _lookahead_revert(&lookahead, pos); if (_is_identifier_char(c)) { strcpy(context->error_msg, "expected a number"); _lookahead_revert(&lookahead, 0); return -1; } if (eaten > sizeof(number) - 1) { strcpy(context->error_msg, "out of memory"); _lookahead_revert(&lookahead, 0); return -1; } assert(_lookahead_tell(&lookahead) == eaten); memcpy(number, _lookahead_buf(&lookahead), eaten); number[eaten] = '\0'; if (is_float) { out->token = SL_PP_FLOAT; out->data._float = sl_pp_context_add_unique_str(context, number); if (out->data._float == -1) { _lookahead_revert(&lookahead, 0); return -1; } } else { out->token = SL_PP_UINT; out->data._uint = sl_pp_context_add_unique_str(context, number); if (out->data._uint == -1) { _lookahead_revert(&lookahead, 0); return -1; } } return 0; }