busybox/testsuite/awk.tests
<<
>>
Prefs
   1#!/bin/sh
   2
   3# Copyright 2007 by Denys Vlasenko <vda.linux@googlemail.com>
   4# Licensed under GPLv2, see file LICENSE in this source tree.
   5
   6. ./testing.sh
   7
   8# testing "description" "command" "result" "infile" "stdin"
   9
  10testing "awk -F case 0" "awk -F '[#]' '{ print NF }'" ""    "" ""
  11testing "awk -F case 1" "awk -F '[#]' '{ print NF }'" "0\n" "" "\n"
  12testing "awk -F case 2" "awk -F '[#]' '{ print NF }'" "2\n" "" "#\n"
  13testing "awk -F case 3" "awk -F '[#]' '{ print NF }'" "3\n" "" "#abc#\n"
  14testing "awk -F case 4" "awk -F '[#]' '{ print NF }'" "3\n" "" "#abc#zz\n"
  15testing "awk -F case 5" "awk -F '[#]' '{ print NF }'" "4\n" "" "#abc##zz\n"
  16testing "awk -F case 6" "awk -F '[#]' '{ print NF }'" "4\n" "" "z#abc##zz\n"
  17testing "awk -F case 7" "awk -F '[#]' '{ print NF }'" "5\n" "" "z##abc##zz\n"
  18
  19# conditions and operators
  20testing "awk if operator == "  "awk 'BEGIN{if(23==23) print \"foo\"}'" "foo\n" "" ""
  21testing "awk if operator != "  "awk 'BEGIN{if(23!=23) print \"bar\"}'" ""      "" ""
  22testing "awk if operator >= "  "awk 'BEGIN{if(23>=23) print \"foo\"}'" "foo\n" "" ""
  23testing "awk if operator < "   "awk 'BEGIN{if(2 < 13) print \"foo\"}'" "foo\n" "" ""
  24testing "awk if string == "    "awk 'BEGIN{if(\"a\"==\"ab\") print \"bar\"}'" "" "" ""
  25
  26# 4294967295 = 0xffffffff
  27testing "awk bitwise op"  "awk '{ print or(4294967295,1) }'" "4294967295\n" "" "\n"
  28
  29# we were testing for a non-empty body when deciding if a function was
  30# defined or not. The testcase below caused:
  31# awk: cmd. line:8: Call to undefined function
  32prg='
  33function empty_fun(count) {
  34  # empty
  35}
  36END {
  37  i=1
  38  print "L" i "\n"
  39  empty_fun(i + i + ++i)
  40  print "L" i "\n"
  41}'
  42testing "awk handles empty function f(arg){}" \
  43        "awk '$prg'" \
  44        "L1\n\nL2\n\n" \
  45        "" ""
  46
  47prg='
  48function outer_fun() {
  49  return 1
  50}
  51END {
  52  i=1
  53  print "L" i "\n"
  54  i += outer_fun()
  55  print "L" i "\n"
  56}'
  57testing "awk properly handles function from other scope" \
  58        "awk '$prg'" \
  59        "L1\n\nL2\n\n" \
  60        "" ""
  61
  62prg='
  63END {
  64  i=1
  65  print "L" i "\n"
  66  i + trigger_error_fun()
  67  print "L" i "\n"
  68}'
  69testing "awk properly handles undefined function" \
  70        "awk '$prg' 2>&1" \
  71        "L1\n\nawk: cmd. line:5: Call to undefined function\n" \
  72        "" ""
  73
  74
  75optional DESKTOP
  76testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n"
  77testing "awk hex const 2" "awk '{ print or(0x80000000,1) }'" "2147483649\n" "" "\n"
  78testing "awk oct const"   "awk '{ print or(01234,1) }'"      "669\n"         "" "\n"
  79SKIP=
  80
  81# check that "hex/oct integer" heuristic doesn't kick in on 00NN.NNN
  82testing "awk floating const with leading zeroes" \
  83        "awk '{ printf \"%f %f\n\", \"000.123\", \"009.123\" }'" \
  84        "0.123000 9.123000\n" \
  85        "" "\n"
  86
  87# long field seps requiring regex
  88testing "awk long field sep" "awk -F-- '{ print NF, length(\$NF), \$NF }'" \
  89        "2 0 \n3 0 \n4 0 \n5 0 \n" \
  90        "" \
  91        "a--\na--b--\na--b--c--\na--b--c--d--"
  92
  93testing "awk -F handles escapes" "awk -F'\\x21' '{print \$1}'" \
  94        "a\n" \
  95        "" \
  96        "a!b\n"
  97
  98# '@(samp|code|file)\{' is an invalid extended regex (unmatched '{'),
  99# but gawk 3.1.5 does not bail out on it.
 100testing "awk gsub falls back to non-extended-regex" \
 101        "awk 'gsub(\"@(samp|code|file)\{\",\"\");'; echo \$?" "0\n" "" "Hi\n"
 102
 103optional TAR BUNZIP2 FEATURE_SEAMLESS_BZ2
 104test x"$SKIP" != x"1" && tar xjf awk_t1.tar.bz2
 105testing "awk 'gcc build bug'" \
 106        "awk -f awk_t1_opt-functions.awk -f awk_t1_opth-gen.awk <awk_t1_input | md5sum" \
 107        "f842e256461a5ab1ec60b58d16f1114f  -\n" \
 108        "" ""
 109rm -rf awk_t1_* 2>/dev/null
 110SKIP=
 111
 112Q='":"'
 113
 114testing "awk NF in BEGIN" \
 115        "awk 'BEGIN { print ${Q} NF ${Q} \$0 ${Q} \$1 ${Q} \$2 ${Q} }'" \
 116        ":0::::\n" \
 117        "" ""
 118
 119prg='
 120function b(tmp) {
 121        tmp = 0;
 122        print "" tmp; #this line causes the bug
 123        return tmp;
 124}
 125function c(tmpc) {
 126        tmpc = b(); return tmpc;
 127}
 128BEGIN {
 129        print (c() ? "string" : "number");
 130}'
 131testing "awk string cast (bug 725)" \
 132        "awk '$prg'" \
 133        "0\nnumber\n" \
 134        "" ""
 135
 136testing "awk handles whitespace before array subscript" \
 137        "awk 'BEGIN { arr [3] = 1; print arr [3] }'" "1\n" "" ""
 138
 139# GNU awk 3.1.5's "print ERRNO" prints "No such file or directory" instead of "2",
 140# do we need to emulate that as well?
 141testing "awk handles non-existing file correctly" \
 142        "awk 'BEGIN { getline line <\"doesnt_exist\"; print ERRNO; ERRNO=0; close(\"doesnt_exist\"); print ERRNO; print \"Ok\" }'" \
 143        "2\n0\nOk\n" "" ""
 144
 145prg='
 146BEGIN {
 147  u["a"]=1
 148  u["b"]=1
 149  u["c"]=1
 150  v["d"]=1
 151  v["e"]=1
 152  v["f"]=1
 153  for (l in u) {
 154    print "outer1", l;
 155    for (l in v) {
 156      print " inner", l;
 157    }
 158    print "outer2", l;
 159  }
 160  print "end", l;
 161  l="a"
 162  exit;
 163}'
 164testing "awk nested loops with the same variable" \
 165        "awk '$prg'" \
 166        "\
 167outer1 a
 168 inner d
 169 inner e
 170 inner f
 171outer2 f
 172outer1 b
 173 inner d
 174 inner e
 175 inner f
 176outer2 f
 177outer1 c
 178 inner d
 179 inner e
 180 inner f
 181outer2 f
 182end f
 183" \
 184        "" ""
 185
 186prg='
 187BEGIN {
 188  u["a"]=1
 189  u["b"]=1
 190  u["c"]=1
 191  v["d"]=1
 192  v["e"]=1
 193  v["f"]=1
 194  for (l in u) {
 195    print "outer1", l;
 196    for (l in v) {
 197      print " inner", l;
 198      break;
 199    }
 200    print "outer2", l;
 201  }
 202  print "end", l;
 203  l="a"
 204  exit;
 205}'
 206# It's not just buggy, it enters infinite loop. Thus disabled
 207false && test x"$SKIP_KNOWN_BUGS" = x"" && testing "awk nested loops with the same variable and break" \
 208        "awk '$prg'" \
 209        "\
 210outer1 a
 211 inner d
 212outer2 d
 213outer1 b
 214 inner d
 215outer2 d
 216outer1 c
 217 inner d
 218outer2 d
 219end d
 220" \
 221        "" ""
 222
 223prg='
 224function f() {
 225  for (l in v) {
 226    print " inner", l;
 227    return;
 228  }
 229}
 230
 231BEGIN {
 232  u["a"]=1
 233  u["b"]=1
 234  u["c"]=1
 235  v["d"]=1
 236  v["e"]=1
 237  v["f"]=1
 238  for (l in u) {
 239    print "outer1", l;
 240    f();
 241    print "outer2", l;
 242  }
 243  print "end", l;
 244  l="a"
 245  exit;
 246}'
 247# It's not just buggy, it enters infinite loop. Thus disabled
 248false && test x"$SKIP_KNOWN_BUGS" = x"" && testing "awk nested loops with the same variable and return" \
 249        "awk '$prg'" \
 250        "\
 251outer1 a
 252 inner d
 253outer2 d
 254outer1 b
 255 inner d
 256outer2 d
 257outer1 c
 258 inner d
 259outer2 d
 260end d
 261" \
 262        "" ""
 263
 264prg='
 265BEGIN{
 266cnt = 0
 267a[cnt] = "zeroth"
 268a[++cnt] = "first"
 269delete a[cnt--]
 270print cnt
 271print "[0]:" a[0]
 272print "[1]:" a[1]
 273}'
 274testing "awk 'delete a[v--]' evaluates v-- once" \
 275        "awk '$prg'" \
 276        "\
 2770
 278[0]:zeroth
 279[1]:
 280" \
 281        "" ""
 282
 283testing "awk handles empty ()" \
 284        "awk 'BEGIN {print()}' 2>&1" "awk: cmd. line:1: Empty sequence\n" "" ""
 285
 286testing "awk FS assignment" "awk '{FS=\":\"; print \$1}'" \
 287        "a:b\ne\n" \
 288        "" \
 289        "a:b c:d\ne:f g:h"
 290
 291optional FEATURE_AWK_LIBM
 292testing "awk large integer" \
 293        "awk 'BEGIN{n=(2^31)-1; print n, int(n), n%1, ++n, int(n), n%1}'" \
 294        "2147483647 2147483647 0 2147483648 2147483648 0\n" \
 295        "" ""
 296SKIP=
 297
 298testing "awk length(array)" \
 299        "awk 'BEGIN{ A[1]=2; A[\"qwe\"]=\"asd\"; print length(A)}'" \
 300        "2\n" \
 301        "" ""
 302
 303testing "awk length()" \
 304        "awk '{print length; print length(); print length(\"qwe\"); print length(99+9)}'" \
 305        "3\n3\n3\n3\n" \
 306        "" "qwe"
 307
 308testing "awk -f and ARGC" \
 309        "awk -f - input" \
 310        "re\n2\n" \
 311        "do re mi\n" \
 312        '{print $2; print ARGC;}' \
 313
 314optional FEATURE_AWK_GNU_EXTENSIONS
 315testing "awk -e and ARGC" \
 316        "awk -e '{print \$2; print ARGC;}' input" \
 317        "re\n2\n" \
 318        "do re mi\n" \
 319        ""
 320SKIP=
 321
 322# The examples are in fact not valid awk programs (break/continue
 323# can only be used inside loops).
 324# But we do accept them outside of loops.
 325# We had a bug with misparsing "break ; else" sequence.
 326# Test that *that* bug is fixed, using simplest possible scripts:
 327testing "awk break" \
 328        "awk -f - 2>&1; echo \$?" \
 329        "0\n" \
 330        "" \
 331        'BEGIN { if (1) break; else a = 1 }'
 332testing "awk continue" \
 333        "awk -f - 2>&1; echo \$?" \
 334        "0\n" \
 335        "" \
 336        'BEGIN { if (1) continue; else a = 1 }'
 337
 338testing "awk handles invalid for loop" \
 339    "awk '{ for() }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" ""
 340
 341# testing "description" "command" "result" "infile" "stdin"
 342testing 'awk negative field access' \
 343        'awk 2>&1 -- '\''{ $(-1) }'\' \
 344        "awk: cmd. line:1: Access to negative field\n" \
 345        '' \
 346        'anything'
 347
 348
 349exit $FAILCOUNT
 350