00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef BNF_H
00026 #define BNF_H
00027
00038 #include <sofia-sip/su_types.h>
00039
00040 #include <string.h>
00041
00042 SOFIA_BEGIN_DECLS
00043
00044
00046 #define CTL "\001\002\003\004\005\006\007" \
00047 "\010\011\012\013\014\015\016\017" \
00048 "\020\021\022\023\024\025\026\027" \
00049 "\030\031\032\033\034\035\036\037" "\177" "\0"
00050
00051 #define SP " "
00052
00053 #define HT "\t"
00054
00055 #define CR "\r"
00056
00057 #define LF "\n"
00058
00059 #define CRLF CR LF
00060
00061 #define WS SP HT
00062
00063 #define LWS SP HT CR LF
00064
00065 #define LOALPHA "abcdefghijklmnopqrstuvwxyz"
00066
00067 #define UPALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00068
00069 #define ALPHA LOALPHA UPALPHA
00070
00071 #define DIGIT "0123456789"
00072
00073 #define SAFE "$-_."
00074 #define ALPHANUM DIGIT ALPHA
00075 #define HEX DIGIT "ABCDEF" "abcdef"
00076
00080 #define SIP_TOKEN ALPHANUM "-.!%*_+`'~"
00081
00082 #define SIP_SEPARATOR "()<>@,;:\\\"/[]?={}" SP HT
00083
00085 #define SIP_WORD "()<>:\\\"/[]?{}"
00086
00088 #define skip_ws(ss) (*(ss) += span_ws(*(ss)))
00089
00091 #define skip_lws(ss) (*(ss) += span_lws(*(ss)))
00092
00094 #define skip_alpha(ss) (*(ss) += span_alpha(*(ss)))
00095
00097 #define skip_digit(ss) (*(ss) += span_digit(*(ss)))
00098
00100 #define skip_alpha_digit_safe(ss) (*(ss) += span_alpha_digit_safe(*(ss)))
00101
00103 #define skip_token(ss) (*(ss) += span_token(*(ss)))
00104
00106 #define skip_param(ss) (*(ss) += span_param(*(ss)))
00107
00109 #define skip_word(ss) (*(ss) += span_word(*(ss)))
00110
00112 #define IS_CRLF(c) ((c) == '\r' || (c) == '\n')
00113
00114 #define IS_LWS(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
00115
00117 #define IS_WS(c) ((c) == ' ' || (c) == '\t')
00118
00119 #define IS_NON_WS(c) (c && !IS_WS(c))
00120
00122 #define IS_NON_LWS(c) (c && !IS_LWS(c))
00123
00125 #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
00126
00127 #define IS_ALPHA(c) (c && ((_bnf_table[(unsigned char)c] & bnf_alpha)))
00128
00129 #define IS_ALPHANUM(c) (c && (IS_DIGIT(c) || IS_ALPHA(c)))
00130
00131 #define IS_UNRESERVED(c) ((_bnf_table[(unsigned char)c] & bnf_unreserved))
00132
00133 #define IS_RESERVED(c) (c && !(_bnf_table[(unsigned char)c] & bnf_unreserved))
00134
00135 #define IS_TOKEN(c) ((_bnf_table[(unsigned char)c] & bnf_token))
00136
00137 #define IS_PARAM(c) ((_bnf_table[(unsigned char)c] & (bnf_token|bnf_param)))
00138
00139 #define IS_HEX(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
00140
00141 #define IS_TOKENLWS(c) ((_bnf_table[(unsigned char)c] & (bnf_token|bn_lws)))
00142
00143 enum {
00144 bnf_ws = 1,
00145 bnf_crlf = 2,
00146 bnf_lws = 3,
00147 bnf_alpha = 4,
00148 bnf_safe = 8,
00149 bnf_mark = 16,
00150 bnf_unreserved = bnf_alpha | bnf_mark,
00151 bnf_separator = 32,
00153 bnf_token0 = 64 | bnf_safe,
00154 bnf_token = bnf_token0 | bnf_alpha,
00155 bnf_param0 = 128,
00156 bnf_param = bnf_token | bnf_param0
00157 };
00158
00160 SOFIAPUBVAR unsigned char const _bnf_table[256];
00161
00163 #define span_non_crlf(s) strcspn(s, CR LF)
00164
00166 #define span_non_ws(s) strcspn(s, WS)
00167
00169 #define span_ws(s) strspn(s, WS)
00170
00172 #define span_non_lws(s) strcspn(s, LWS)
00173
00177 static inline isize_t span_lws(char const *s)
00178 {
00179 char const *e = s;
00180 int i = 0;
00181 e += strspn(s, WS);
00182 if (e[i] == '\r') i++;
00183 if (e[i] == '\n') i++;
00184 if (IS_WS(e[i]))
00185 e += i + strspn(e + i, WS);
00186 return e - s;
00187 }
00188
00190 static inline isize_t span_token_lws(char const *s)
00191 {
00192 char const *e = s;
00193 while (_bnf_table[(unsigned char)(*e)] & (bnf_token | bnf_lws))
00194 e++;
00195 return e - s;
00196 }
00197
00198 #if 1
00199
00200 static inline isize_t span_token(char const *s)
00201 {
00202 char const *e = s;
00203 while (_bnf_table[(unsigned char)(*e)] & bnf_token)
00204 e++;
00205 return e - s;
00206 }
00207 #else
00208 size_t bnf_span_token(char const *s);
00209 #define span_token(s) bnf_span_token((s))
00210 #endif
00211
00212
00214 static inline isize_t span_alpha(char const *s)
00215 {
00216 char const *e = s;
00217 while (_bnf_table[(unsigned char)(*e)] & bnf_alpha)
00218 e++;
00219 return e - s;
00220 }
00221
00223 static inline isize_t span_digit(char const *s)
00224 {
00225 char const *e = s;
00226 while (*e >= '0' && *e <= '9')
00227 e++;
00228 return e - s;
00229 }
00230
00232 static inline isize_t span_hexdigit(char const *s)
00233 {
00234 char const *e = s;
00235 while (IS_HEX(*e))
00236 e++;
00237 return e - s;
00238 }
00239
00241 static inline isize_t span_alpha_digit_safe(char const *s)
00242 {
00243 char const *e = s;
00244 while (_bnf_table[(unsigned char)(*e)] & (bnf_alpha | bnf_safe))
00245 e++;
00246 return e - s;
00247 }
00248
00250 static inline isize_t span_param(char const *s)
00251 {
00252 char const *e = s;
00253 while (IS_PARAM(*e))
00254 e++;
00255 return e - s;
00256 }
00257
00259 static inline isize_t span_word(char const *s)
00260 {
00261 char const *e = s;
00262 while (*e && (IS_TOKEN(*e) || strchr(SIP_WORD, *e)))
00263 e++;
00264 return e - s;
00265 }
00266
00268 static inline isize_t span_unreserved(char const *s)
00269 {
00270 char const *e = s;
00271 while (IS_UNRESERVED(*e))
00272 e++;
00273 return e - s;
00274 }
00275
00277 static inline isize_t span_quoted(char const *s)
00278 {
00279 char const *b = s;
00280
00281 if (*s++ != '"')
00282 return 0;
00283
00284 for (;;) {
00285 s += strcspn(s, "\\\"");
00286 if (!*s)
00287 return 0;
00288 if (*s++ == '"')
00289 return s - b;
00290 if (!*s++)
00291 return 0;
00292 }
00293 }
00294
00295
00297 #define URL_RESERVED ";/?:=+$,"
00298
00300 #define URL_MARK "-_.!~*'()"
00301
00303 #define URL_UNRESERVED ALPHANUM URL_MARK
00304
00306 #define URL_ESCAPED "%"
00307 #define URL_DELIMS "<>#%\""
00308 #define URL_UNWISE "{}|\\^[]`"
00309 #define URL_SCHEME ALPHANUM "+-."
00310
00312 #define span_url_scheme(s) strspn(s, URL_SCHEME)
00313
00314 SOFIAPUBFUN int span_ip4_address(char const *host);
00315 SOFIAPUBFUN int span_ip6_address(char const *host);
00316 SOFIAPUBFUN int span_ip6_reference(char const *host);
00317 SOFIAPUBFUN int span_ip_address(char const *host);
00318 SOFIAPUBFUN isize_t span_domain(char const *host);
00319 SOFIAPUBFUN isize_t span_host(char const *host);
00320
00321 SOFIAPUBFUN int scan_ip4_address(char **inout_host);
00322 SOFIAPUBFUN int scan_ip6_address(char **inout_host);
00323 SOFIAPUBFUN int scan_ip6_reference(char **inout_host);
00324 SOFIAPUBFUN int scan_ip_address(char **inout_host);
00325 SOFIAPUBFUN issize_t scan_domain(char **inout_host);
00326 SOFIAPUBFUN issize_t scan_host(char **inout_host);
00327
00328 SOFIA_END_DECLS
00329
00330 #endif