Index: llvm/utils/lit/lit/TestRunner.py =================================================================== --- llvm/utils/lit/lit/TestRunner.py +++ llvm/utils/lit/lit/TestRunner.py @@ -365,7 +365,7 @@ """executeBuiltinDiff - Compare files line by line.""" args = expand_glob_expressions(cmd.args, cmd_shenv.cwd)[1:] try: - opts, args = getopt.gnu_getopt(args, "wbur", ["strip-trailing-cr"]) + opts, args = getopt.gnu_getopt(args, "wbuU:r", ["strip-trailing-cr"]) except getopt.GetoptError as err: raise InternalShellError(cmd, "Unsupported: 'diff': %s" % str(err)) @@ -373,6 +373,7 @@ ignore_all_space = False ignore_space_change = False unified_diff = False + num_context_lines = 3 recursive_diff = False strip_trailing_cr = False for o, a in opts: @@ -382,6 +383,16 @@ ignore_space_change = True elif o == "-u": unified_diff = True + elif o.startswith("-U"): + unified_diff = True + try: + num_context_lines = int(a) + if num_context_lines < 0: + raise ValueException + except: + raise InternalShellError(cmd, + "Error: invalid '-U' argument: {}\n" + .format(a)) elif o == "-r": recursive_diff = True elif o == "--strip-trailing-cr": @@ -433,12 +444,16 @@ exitCode = 0 if hasattr(difflib, 'diff_bytes'): # python 3.5 or newer - diffs = difflib.diff_bytes(difflib.unified_diff, filelines[0], filelines[1], filepaths[0].encode(), filepaths[1].encode()) + diffs = difflib.diff_bytes(difflib.unified_diff, filelines[0], + filelines[1], filepaths[0].encode(), + filepaths[1].encode(), + n = num_context_lines) diffs = [diff.decode() for diff in diffs] else: # python 2.7 func = difflib.unified_diff if unified_diff else difflib.context_diff - diffs = func(filelines[0], filelines[1], filepaths[0], filepaths[1]) + diffs = func(filelines[0], filelines[1], filepaths[0], filepaths[1], + n = num_context_lines) for diff in diffs: stdout.write(diff) @@ -471,7 +486,8 @@ filelines[idx]= [f(line) for line in lines] func = difflib.unified_diff if unified_diff else difflib.context_diff - for diff in func(filelines[0], filelines[1], filepaths[0], filepaths[1]): + for diff in func(filelines[0], filelines[1], filepaths[0], filepaths[1], + n = num_context_lines): stdout.write(diff) exitCode = 1 return exitCode Index: llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified-error-0.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified-error-0.txt @@ -0,0 +1,3 @@ +# Check bad -U argument. +# RUN: echo foo > %t +# RUN: diff -U 30.1 %t %t Index: llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified-error-1.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified-error-1.txt @@ -0,0 +1,3 @@ +# Check bad -U argument. +# RUN: echo foo > %t +# RUN: diff -U-1 %t %t Index: llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified.txt =================================================================== --- /dev/null +++ llvm/utils/lit/tests/Inputs/shtest-shell/diff-unified.txt @@ -0,0 +1,34 @@ +# RUN: echo 1 > %t.foo +# RUN: echo 2 >> %t.foo +# RUN: echo 3 >> %t.foo +# RUN: echo 4 >> %t.foo +# RUN: echo 5 >> %t.foo +# RUN: echo 6 foo >> %t.foo +# RUN: echo 7 >> %t.foo +# RUN: echo 8 >> %t.foo +# RUN: echo 9 >> %t.foo +# RUN: echo 10 >> %t.foo +# RUN: echo 11 >> %t.foo + +# RUN: echo 1 > %t.bar +# RUN: echo 2 >> %t.bar +# RUN: echo 3 >> %t.bar +# RUN: echo 4 >> %t.bar +# RUN: echo 5 >> %t.bar +# RUN: echo 6 bar >> %t.bar +# RUN: echo 7 >> %t.bar +# RUN: echo 8 >> %t.bar +# RUN: echo 9 >> %t.bar +# RUN: echo 10 >> %t.bar +# RUN: echo 11 >> %t.bar + +# Default is 3 lines of context. +# RUN: diff -u %t.foo %t.bar && false || true + +# Override default of 3 lines of context. +# RUN: diff -U 2 %t.foo %t.bar && false || true +# RUN: diff -U4 %t.foo %t.bar && false || true +# RUN: diff -U0 %t.foo %t.bar && false || true + +# Fail so lit will print output. +# RUN: false Index: llvm/utils/lit/tests/max-failures.py =================================================================== --- llvm/utils/lit/tests/max-failures.py +++ llvm/utils/lit/tests/max-failures.py @@ -8,7 +8,7 @@ # # END. -# CHECK: Failing Tests (27) +# CHECK: Failing Tests (30) # CHECK: Failing Tests (1) # CHECK: Failing Tests (2) # CHECK: error: argument --max-failures: requires positive integer, but found '0' Index: llvm/utils/lit/tests/shtest-shell.py =================================================================== --- llvm/utils/lit/tests/shtest-shell.py +++ llvm/utils/lit/tests/shtest-shell.py @@ -149,6 +149,86 @@ # CHECK: PASS: shtest-shell :: diff-r.txt +# CHECK: FAIL: shtest-shell :: diff-unified-error-0.txt +# CHECK: *** TEST 'shtest-shell :: diff-unified-error-0.txt' FAILED *** +# CHECK: $ "diff" "-U" "30.1" "{{[^"]*}}" "{{[^"]*}}" +# CHECK: # command stderr: +# CHECK: Error: invalid '-U' argument: 30.1 +# CHECK: error: command failed with exit status: 127 +# CHECK: *** + +# CHECK: FAIL: shtest-shell :: diff-unified-error-1.txt +# CHECK: *** TEST 'shtest-shell :: diff-unified-error-1.txt' FAILED *** +# CHECK: $ "diff" "-U-1" "{{[^"]*}}" "{{[^"]*}}" +# CHECK: # command stderr: +# CHECK: Error: invalid '-U' argument: -1 +# CHECK: error: command failed with exit status: 127 +# CHECK: *** + + +# CHECK: FAIL: shtest-shell :: diff-unified.txt + +# CHECK: *** TEST 'shtest-shell :: diff-unified.txt' FAILED *** + +# CHECK: $ "diff" "-u" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 3 +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-NEXT: 9 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U" "2" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U4" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 2 +# CHECK-NEXT: 3 +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-NEXT: 9 +# CHECK-NEXT: 10 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U0" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "false" + +# CHECK: *** + + # CHECK: FAIL: shtest-shell :: error-0.txt # CHECK: *** TEST 'shtest-shell :: error-0.txt' FAILED *** # CHECK: $ "not-a-real-command" @@ -228,4 +308,4 @@ # CHECK: PASS: shtest-shell :: sequencing-0.txt # CHECK: XFAIL: shtest-shell :: sequencing-1.txt # CHECK: PASS: shtest-shell :: valid-shell.txt -# CHECK: Failing Tests (27) +# CHECK: Failing Tests (30)