diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index a308a5720e05004033a48917cbebad037378c826..43bd26134f64d17c19a617b30511def101410cf8 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -103,6 +103,63 @@ static s64 hextol(const char *s) return strtol(yytext + 2, NULL, 16); } +enum ifdef_os { + Linux_IFDEF = 1, FreeBSD_IFDEF, NetBSD_IFDEF +}; + + #define MAX_IFDEF_DEPTH 10 +YY_BUFFER_STATE ifdef_stack[MAX_IFDEF_DEPTH]; +int ifdef_stack_ptr = 0; + +static void handle_ifdef(enum ifdef_os os, const char *s) { + char *code = strdup(s); + + unsigned int ifdef_length = 10; + unsigned int endif_length = 10; + unsigned int os_name_length = 0; + + switch (os) { + case Linux_IFDEF: + printf("ifdef linux called:"); + os_name_length = 5; + break; + case FreeBSD_IFDEF: + printf("ifdef freebsd called:"); + os_name_length = 7; + break; + case NetBSD_IFDEF: + printf("ifdef netbsd called:"); + os_name_length = 6; + break; + } + +#ifdef linux + if (os != Linux_IFDEF) { + return; + } +#endif +#ifdef __FreeBSD__ + if (os != FreeBSD_IFDEF) { + return; + } +#endif + + char *code_without_ifdef = code+ifdef_length+os_name_length; + code_without_ifdef[strlen(code_without_ifdef) - (endif_length + os_name_length)] = (char) 0; +// fprintf( stdout, "\n%s\n", code_without_ifdef); + + if (ifdef_stack_ptr >= MAX_IFDEF_DEPTH) { + fprintf(stderr, "Ifdefs nested too deeply"); + exit(1); + } + + ifdef_stack[ifdef_stack_ptr++] = YY_CURRENT_BUFFER; + YY_BUFFER_STATE state = yy_scan_string(code_without_ifdef); + yy_switch_to_buffer(state); + + free(code); +} + %} %{ @@ -122,6 +179,13 @@ cpp_comment \/\/[^\n]*\n */ c_comment \/\*(([^*])|(\*[^\/]))*\*\/ + +ifdef_begin __ifdef__ +ifdef_end __endif__ + +ifdef_regex_freebsd {ifdef_begin}FreeBSD(.|\n)*{ifdef_end}FreeBSD +ifdef_regex_linux {ifdef_begin}Linux(.|\n)*{ifdef_end}Linux + /* The regexp for code snippets is analogous to that for C comments. * Here is a summary of the regexp for code snippets: * %{ @@ -452,7 +516,21 @@ NULL return NULL_; [ \t\n]+ /* ignore whitespace */; {cpp_comment} /* ignore C++-style comment */; {c_comment} /* ignore C-style comment */; +{ifdef_regex_freebsd} handle_ifdef(FreeBSD_IFDEF, yytext); +{ifdef_regex_linux} handle_ifdef(Linux_IFDEF, yytext); {code} yylval.string = code(yytext); return CODE; {ipv4_addr} yylval.string = strdup(yytext); return IPV4_ADDR; {ipv6_addr} yylval.string = strdup(yytext); return IPV6_ADDR; + <<EOF>> { + if ( --ifdef_stack_ptr < 0 ) + { + yyterminate(); + } + + else + { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(ifdef_stack[ifdef_stack_ptr]); + } + } %% diff --git a/gtests/net/packetdrill/tests/bsd/sctp/ifdef_testcase.pkt b/gtests/net/packetdrill/tests/bsd/sctp/ifdef_testcase.pkt new file mode 100644 index 0000000000000000000000000000000000000000..db776d5fbc9172a26d09f8bcee6f33e18a26a433 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/ifdef_testcase.pkt @@ -0,0 +1,26 @@ +// Create a non-blocking 1-to-1 style socket + 0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3 ++0.0 bind(3, ..., ...) = 0 ++0.0 fcntl(3, F_GETFL) = 0x02 (flags O_RDWR) ++0.0 fcntl(3, F_SETFL, O_RDWR | O_NONBLOCK) = 0 +// Trigger the active associtation setup ++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) ++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=0, ...] ++0.0 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]] ++0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...] ++0.0 < sctp: COOKIE_ACK[flgs=0] +// Check if the setup was sucessful ++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 +// inject sack-chunk(type=3) with invalid len=8| cumulative tsn ack | ++0.0 < sctp: CHUNK[type=3, flgs=0, len=8, val=[0x00, 0x00, 0x00, 0x01]] +__ifdef__Linux +// expect protocol violation ++0.0 > sctp: ABORT[flgs=..., PROTOCOL_VIOLATION[info=...]] +__endif__Linux +__ifdef__FreeBSD ++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 ++0.0 close(3) = 0 ++0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=0] ++0.1 < sctp: SHUTDOWN_ACK[flgs=0] ++0.0 > sctp: SHUTDOWN_COMPLETE[flgs=0] +__endif__FreeBSD