# BST-TIMEOUT: 1200 # 53 cases, 81s measured locally; the nightly's browser run still exceeds 300s . "$BST_LIB" require flex flex/present tmp=${TMPDIR:-/tmp}/bst-flex.$$ mkdir -p "$tmp" || { bst_notok flex/tmpdir "cannot create $tmp"; return 2>/dev/null || exit 0; } cd "$tmp" || { bst_notok flex/chdir "cannot cd $tmp"; return 2>/dev/null || exit 0; } # ---------------------------------------------------------------- fixtures cat > num.l <<'LEX' %option noyywrap DIGIT [0-9] %{ #define FLEX_SELFTEST_MARKER 1 %} %x COMMENT %% {DIGIT}+ { return 1; } [a-z]+ { return 2; } "/*" { BEGIN(COMMENT); } "*/" { BEGIN(INITIAL); } .|\n { } .|\n { } %% LEX cat > bad.l <<'LEX' %% [ { return 1; } %% LEX # ------------------------------------------------- 1. shipped payload check_out flex/version "flex 2.6.4" flex --version check_out flex/version-V "flex 2.6.4" flex -V check_out flex/help "--outfile" flex --help check flex/flexpp-present test -x /usr/bin/flex++ check flex/m4-present test -x /usr/bin/m4 # ------------------------------------------------- 2. default generation rm -f lex.yy.c check flex/gen-default flex num.l check flex/gen-lexyyc test -s lex.yy.c check_out flex/gen-yylex "yylex" cat lex.yy.c check_out flex/gen-buf "YY_BUF_SIZE" cat lex.yy.c # the m4 filter chain must have fully expanded the skeleton: no macro residue n=$(grep -c 'm4_' lex.yy.c 2>/dev/null || true) check_eq flex/gen-no-m4-residue 0 "$n" n=$(grep -c 'M4_YY' lex.yy.c 2>/dev/null || true) check_eq flex/gen-no-M4_YY 0 "$n" # the scanner really encodes this grammar: the action bodies survive check_out flex/gen-action "return 1;" cat lex.yy.c check_out flex/gen-startcond "COMMENT" cat lex.yy.c check_out flex/gen-cblock "FLEX_SELFTEST_MARKER" cat lex.yy.c check_out flex/gen-table "yy_accept" cat lex.yy.c # -o names the output rm -f out.c check flex/opt-outfile flex -o out.c num.l check flex/opt-outfile-exists test -s out.c # Generation is deterministic. Compare two runs writing the SAME output name: # the #line directives embed the output filename, so two runs to *different* # names differ by exactly those lines and byte-comparing them would be a false red. flex -o same.c num.l 2>/dev/null; cp same.c det1.c flex -o same.c num.l 2>/dev/null; cp same.c det2.c check flex/gen-deterministic cmp -s det1.c det2.c # ...and the corollary: with --noline suppressed, even different output names # produce byte-identical scanners, so the line directives are the only variance. flex --noline -o nl1.c num.l 2>/dev/null flex --noline -o nl2.c num.l 2>/dev/null check flex/gen-noline-deterministic cmp -s nl1.c nl2.c # The #line directives name the OUTPUT file (the ones naming the input .l file # are m4's, passed through untouched). Their numeric VALUE is deliberately not # pinned: flex rewrites these in filter_fix_linedirs, a forked filter whose line # counter runs one behind on this target, so each self-referencing directive # declares its own physical line where a host build declares the following one. # The scanner is otherwise byte-identical and nothing on this image compiles it. check flex/gen-line-names-output sh -c 'grep -q "^#line [0-9][0-9]* \"same.c\"$" same.c' n=$(grep -c '^#line [0-9][0-9]* "same.c"$' same.c 2>/dev/null || true) check_eq flex/gen-line-count 6 "$n" # -t writes the scanner to stdout check_out flex/opt-stdout "yylex" flex -t num.l # ------------------------------------------- 3. the m4 pipeline (fork/exec) # flex pipes the skeleton through m4; a bogus $M4 must therefore break it, # which is what proves the subprocess is real and not short-circuited. rm -f m4bad.c out=$(M4=/nonexistent-m4-xyz flex -o m4bad.c num.l 2>&1); rc=$? if [ "$rc" -ne 0 ] || [ ! -s m4bad.c ]; then bst_ok flex/m4-required else bst_notok flex/m4-required "rc=$rc with M4=/nonexistent-m4-xyz, output still produced"; fi rm -f m4ok.c check flex/m4-env-honored sh -c 'M4=/usr/bin/m4 flex -o m4ok.c num.l' check flex/m4-env-output test -s m4ok.c # --header-file forks the filter chain a second time rm -f hdr.c hdr.h check flex/header-file flex -o hdr.c --header-file=hdr.h num.l check flex/header-exists test -s hdr.h check_out flex/header-decl "yylex" cat hdr.h check_out flex/header-guard "#ifndef" cat hdr.h # ------------------------------------------------- 4. option surface check_out flex/opt-prefix "foolex" sh -c 'flex -t -Pfoo num.l' check_out flex/opt-reentrant "yylex_init" sh -c 'flex -t -R num.l' check_out flex/opt-cxx "yyFlexLexer" sh -c 'flex -t -+ num.l' check_out flex/flexpp-cxx "yyFlexLexer" sh -c 'flex++ -t num.l' check_out flex/opt-debug "yy_flex_debug" sh -c 'flex -t -d num.l' check_out flex/opt-yylineno "yylineno" sh -c 'flex -t --yylineno num.l' check_out flex/opt-line "#line" sh -c 'flex -t num.l' n=$(flex -t --noline num.l 2>/dev/null | grep -c '^#line' || true) check_eq flex/opt-noline 0 "$n" check flex/opt-8bit sh -c 'flex -8 -o e8.c num.l' check flex/opt-caseless sh -c 'flex -i -o ei.c num.l' check flex/opt-fulltable sh -c 'flex -Cf -o ecf.c num.l' check flex/opt-fasttable sh -c 'flex -CF -o ecF.c num.l' # --tables-file serialises the DFA tables to their own file rm -f tab.bin tabs.c check flex/tables-file sh -c 'flex -Cf --tables-file=tab.bin -o tabs.c num.l' check flex/tables-file-exists test -s tab.bin # -b writes the backing-up report rm -f lex.backup check flex/opt-backup sh -c 'flex -b -o eb.c num.l' check flex/opt-backup-report test -f lex.backup # ------------------------------------------------- 5. input handling check_out flex/stdin "yylex" sh -c 'flex -t < num.l' printf '%%%%\n[0-9]+ { return 7; }\n' > two.l check flex/second-file sh -c 'flex -o two.c two.l' # ------------------------------------------------- 6. exit-status contracts out=$(flex -o miss.c nosuchfile.l 2>&1); rc=$? check_eq flex/rc-missing-input 1 "$rc" case "$out" in *"can't open"*|*"No such file"*) bst_ok flex/msg-missing-input ;; *) bst_notok flex/msg-missing-input "$(_bst_1line "$out")" ;; esac out=$(flex -Z num.l 2>&1); rc=$? if [ "$rc" -ne 0 ]; then bst_ok flex/rc-bad-option else bst_notok flex/rc-bad-option "unknown option -Z exited 0"; fi case "$out" in *nknown*|*nrecognized*|*invalid*) bst_ok flex/msg-bad-option ;; *) bst_notok flex/msg-bad-option "$(_bst_1line "$out")" ;; esac out=$(flex -o badout.c bad.l 2>&1); rc=$? if [ "$rc" -ne 0 ]; then bst_ok flex/rc-syntax-error else bst_notok flex/rc-syntax-error "malformed rule exited 0"; fi out=$(flex -o good.c num.l 2>&1); rc=$? check_eq flex/rc-ok 0 "$rc" cd / rm -rf "$tmp"