📄 bnf.c
字号:
if (span > maxspan) doublecolon = i - span, maxspan = span; dst = buf; for (i = 0; i < maxparts; i++) { if (i == doublecolon) hex = i == 0 ? "::" : ":", len = 1; else if (i > doublecolon && i < doublecolon + maxspan) continue; else hex = hexparts[i], len = span_hex4(hex); if (hex[len] == ':') len++; memcpy(dst, hex, len); dst += len; } if (ip4) { hex = ip4; len = scan_ip4_address(&hex); assert(len > 0); /* Canonize :: and ::1 */ if (doublecolon == 0 && maxspan == 6) { if (len == 7 && strncmp(ip4, "0.0.0.0", len) == 0) ip4 = "", len = 0; else if (len == 7 && strncmp(ip4, "0.0.0.1", len) == 0) ip4 = "1", len = 1; } memcpy(dst, ip4, len); dst += len; } len = dst - buf; memcpy(host, buf, len); return len;}/** Return length of valid IP6 address */int span_ip6_address(char const *host){ return span_canonic_ip6_address(host, NULL, NULL);}/** Scan and canonize valid IP6 address. * * @param inout_host input pointer to string to scan * output pointer to first character after valid IP6 address * * @retval Length of valid IP6 address or -1 upon an error. * * @note Scanned IP6 is not NUL-terminated. */int scan_ip6_address(char **inout_host){ int n, canonize = 0; char *host = *inout_host; char *hexparts[9] = { NULL }; n = span_canonic_ip6_address(host, &canonize, hexparts); if (n == 0) return -1; *inout_host += n; if (canonize) { int len = canonize_ip6_address(host, hexparts); assert(len <= n); if (len < n) host[len] = '\0'; } return n;}/** Return length of valid IP6 reference. */int span_ip6_reference(char const *host){ /* IPv6reference = "[" IPv6address "]" */ if (host[0] == '[') { int n = span_ip6_address(host + 1); if (n > 0 && host[n + 1] == ']') return n + 2; } return 0;}/** Scan valid IP6 reference. */int scan_ip6_reference(char **inout_host){ int n, canonize = 0; char *host = *inout_host; char *hexparts[9] = { NULL }; /* IPv6reference = "[" IPv6address "]" */ if (host == NULL || host[0] != '[' || (n = span_canonic_ip6_address(host + 1, &canonize, hexparts)) == 0 || host[n + 1] != ']') return -1; *inout_host += n + 2; if (canonize) { int len = canonize_ip6_address(host + 1, hexparts); assert(len <= n); host[len + 1] = ']'; if (len + 2 < n + 2) host[len + 2] = '\0'; } return n + 2;}/** Return length of valid IP4 or IP6 address. */int span_ip_address(char const *host){ if (!host || !host[0]) return 0; /* IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet */ if (IS_DIGIT(host[0])) { int n = span_ip4_address(host); if (n) return n; } if (host[0] == '[') return span_ip6_reference(host); else return span_ip6_address(host);}/** Scan valid IP4/IP6 address. */int scan_ip_address(char **inout_host){ char *host = *inout_host; if (host == NULL) return -1; /* IPv6reference = "[" IPv6address "]" */ if (host[0] == '[') return scan_ip6_reference(inout_host); if (IS_DIGIT(host[0])) { int n = scan_ip4_address(inout_host); if (n > 0) return n; } return scan_ip6_address(inout_host);}/** Return length of a valid domain label */static inlineint span_domain_label(char const *label){ /* domainlabel = alphanum / alphanum *( alphanum / "-" ) alphanum */ if (IS_ALPHANUM(*label)) { int n; for (n = 1; IS_ALPHANUM(label[n]) || label[n] == '-'; n++) ; if (IS_ALPHANUM(label[n - 1])) return n; } return 0;}/** Scan valid domain name and count number of labels in it. */static inlineint span_domain_labels(char const *host, int *return_labels){ int len, n, labels, c; if (!host || !host[0]) return 0; for (n = 0, labels = 0; ; n += len) { len = span_domain_label(host + n); if (len == 0) return 0; labels++; if (host[n + len] != '.') break; len++; if (!IS_ALPHANUM(host[n + len])) break; } /* Check that last label does not start with number */ if (!IS_ALPHA(host[n])) return 0; c = host[n + len]; if (IS_ALPHANUM(c) || c == '-' || c == '.') return 0; if (return_labels) *return_labels = labels; return n + len;}/** Return length of a valid domain name. * * @code * hostname = *( domainlabel "." ) toplabel [ "." ] * domainlabel = alphanum * / alphanum *( alphanum / "-" ) alphanum * toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum * @endcode */int span_domain(char const *host){ return span_domain_labels(host, NULL);}/** Scan valid domain name. */int scan_domain(char **inout_host){ char *host; int n, labels; n = span_domain_labels(host = *inout_host, &labels); if (n == 0) return -1; /* Remove extra dot at the end of hostname */ if (labels > 1 && host[n - 1] == '.') host[n - 1] = '\0'; *inout_host += n; return n;}/** Return length of a valid domain name or IP address. */int span_host(char const *host){ if (!host || !host[0]) return 0; if (host[0] == '[') return span_ip6_reference(host); if (IS_DIGIT(host[0])) { int n = span_ip4_address(host); if (n) return n; } return span_domain(host);}/** Scan valid domain name or IP address. */int scan_host(char **inout_host){ char *host = *inout_host; if (host == NULL) return -1; /* IPv6reference = "[" IPv6address "]" */ if (host[0] == '[') return scan_ip6_reference(inout_host); if (IS_DIGIT(host[0])) { int n = scan_ip4_address(inout_host); if (n > 0) return n; } return scan_domain(inout_host);}#include <sofia-sip/hostdomain.h>/** Return true if @a string is valid IP4 address in dot-notation. * * @note Only 4-octet form is accepted, e.g., @c 127.1 is not considered * valid IP4 address. */int host_is_ip4_address(char const *string){ int n = span_ip4_address(string); return n > 0 && string[n] == '\0';}/** Return true if @a string is valid IP6 address in hex notation. * * E.g., fe80::1 is a valid IP6 address. */int host_is_ip6_address(char const *string){ int n = span_ip6_address(string); return n > 0 && string[n] == '\0';}/** Return true if @a string is valid IP6 reference, * i.e. hex notation in square brackets. * * E.g., [::1] is a valid IP6 reference. */int host_ip6_reference(char const *string){ int n = span_ip6_reference(string); return n > 0 && string[n] == '\0';}/** Return true if @a string is valid IP address. * * Valid IP address is either a IP4 adddress in quad-octet notation, * IP6 hex address or IP6 reference in square brackets ([]). */int host_is_ip_address(char const *string){ int n = span_ip_address(string); return n > 0 && string[n] == '\0';}/** Return true if @a string is valid a domain name. * * Valid domain name consists of alphanumeric labels separated with * dot ("."). There can be a "-" in the middle of label. * The last label must start with a letter. * * @code * hostname = *( domainlabel "." ) toplabel [ "." ] * domainlabel = alphanum * / alphanum *( alphanum / "-" ) alphanum * toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum * @endcode */int host_is_domain(char *string){ int n = span_domain(string); return n > 0 && string[n] == '\0';}/** Return true if @a string is valid a host name. * * Check if the @a string is a domain name, IP address or IP6 reference. */int host_is_valid(char const *string){ int n = span_host(string); return n > 0 && string[n] == '\0';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -