From a65795f10ab268c2b2c4e079c715eca6f47c2239 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 18 Feb 2012 18:15:18 +0000 Subject: [PATCH] Re-implement tracediff.sh on Python. --- CMakeLists.txt | 2 +- cli/cli_diff.cpp | 78 ++++++++++--------------- scripts/tracediff.py | 134 +++++++++++++++++++++++++++++++++++++++++++ scripts/tracediff.sh | 59 ------------------- 4 files changed, 164 insertions(+), 109 deletions(-) create mode 100755 scripts/tracediff.py delete mode 100755 scripts/tracediff.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ac9676..6469b4b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -630,7 +630,7 @@ add_subdirectory(cli) install ( PROGRAMS - ${CMAKE_CURRENT_SOURCE_DIR}/scripts/tracediff.sh + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/tracediff.py ${CMAKE_CURRENT_SOURCE_DIR}/scripts/jsondiff.py ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snapdiff.py DESTINATION ${SCRIPTS_INSTALL_DIR} diff --git a/cli/cli_diff.cpp b/cli/cli_diff.cpp index 9f6efef..f03e02d 100644 --- a/cli/cli_diff.cpp +++ b/cli/cli_diff.cpp @@ -35,14 +35,26 @@ static const char *synopsis = "Identify differences between two traces."; +static os::String +find_command(void) +{ + return trace::findScript("tracediff.py"); +} + static void usage(void) { - std::cout - << "usage: apitrace diff \n" - << synopsis << "\n" - "\n" - " Both input files should be the result of running 'apitrace trace'.\n"; + os::String command = find_command(); + if (!command.length()) { + exit(1); + } + + char *args[3]; + args[0] = (char *) command.str(); + args[1] = (char *) "--help"; + args[2] = NULL; + + os::execute(args); } static int @@ -50,55 +62,23 @@ command(int argc, char *argv[]) { int i; - for (i = 1; i < argc; ++i) { - const char *arg = argv[i]; - - if (arg[0] != '-') { - break; - } - - if (!strcmp(arg, "--")) { - i++; - break; - } else if (!strcmp(arg, "--help")) { - usage(); - return 0; - } else { - std::cerr << "error: unknown option " << arg << "\n"; - usage(); - return 1; - } - } - - if (argc - i != 2) { - std::cerr << "Error: diff requires exactly two trace files as arguments.\n"; - usage(); + os::String command = find_command(); + if (!command.length()) { return 1; } - char *file1, *file2; - - file1 = argv[i]; - file2 = argv[i+1]; - - os::String command = trace::findScript("tracediff.sh"); + os::String apitracePath = os::getProcessName(); - char* args[4]; - - args[0] = (char *) command.str(); - args[1] = file1; - args[2] = file2; - args[3] = NULL; - -#ifdef _WIN32 - std::cerr << "The 'apitrace diff' command is not yet supported on this O/S.\n"; - return 1; -#else - os::String apitrace = os::getProcessName(); - setenv("APITRACE", apitrace.str(), 1); + std::vectorargs; + args.push_back(command.str()); + args.push_back("--apitrace"); + args.push_back(apitracePath.str()); + for (i = 1; i < argc; i++) { + args.push_back(argv[i]); + } + args.push_back(NULL); - return os::execute(args); -#endif + return os::execute((char * const *)&args[0]); } const Command diff_command = { diff --git a/scripts/tracediff.py b/scripts/tracediff.py new file mode 100755 index 0000000..827293d --- /dev/null +++ b/scripts/tracediff.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2011 Jose Fonseca +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +##########################################################################/ + + +import platform +import optparse +import os +import shutil +import subprocess +import sys +import tempfile + + +def stripdump(trace, fifo): + dump = subprocess.Popen( + args = [ + options.apitrace, + 'dump', + '--color=never', + '--arg-names=no', + '--calls=' + options.calls, + trace + ], + stdout = subprocess.PIPE, + universal_newlines = True, + ) + + sed = subprocess.Popen( + args = [ + 'sed', + '-e', r's/\r$//g', + '-e', r's/^[0-9]\+ //', + '-e', r's/hdc = \w\+/hdc/g', + ], + stdin = dump.stdout, + stdout = open(fifo, 'wt') + universal_newlines = True, + ) + + +def diff(traces): + fifodir = tempfile.mkdtemp() + try: + fifos = [] + for i in range(len(traces)): + trace = traces[i] + fifo = os.path.join(fifodir, str(i)) + stripdump(trace, fifo) + fifos.append(fifo) + + # TODO use difflib instead + sdiff = subprocess.Popen( + args = [ + 'sdiff', + '--width=%u' % options.width, + '--speed-large-files', + ] + fifos, + stdout = subprocess.PIPE + universal_newlines = True, + ) + + less = subprocess.Popen( + args = ['less', '-FRXn'], + stdin = sdiff.stdout + ) + + less.wait() + + finally: + shutil.rmtree(fifodir) + + +def columns(): + import curses + curses.setupterm() + return curses.tigetnum('cols') + + +def main(): + '''Main program. + ''' + + default_width = columns() + + # Parse command line options + optparser = optparse.OptionParser( + usage='\n\t%prog [options] -- TRACE_FILE TRACE_FILE', + version='%%prog') + optparser.add_option( + '-a', '--apitrace', metavar='PROGRAM', + type='string', dest='apitrace', default='apitrace', + help='apitrace command [default: %default]') + optparser.add_option( + '-c', '--calls', metavar='CALLSET', + type="string", dest="calls", default='1-10000', + help="calls to compare [default: %default]") + optparser.add_option( + '-w', '--width', metavar='NUM', + type="string", dest="width", default=default_width, + help="columns [default: %default]") + + global options + (options, args) = optparser.parse_args(sys.argv[1:]) + if len(args) != 2: + optparser.error("incorrect number of arguments") + + diff(args) + + +if __name__ == '__main__': + main() diff --git a/scripts/tracediff.sh b/scripts/tracediff.sh deleted file mode 100755 index 819a251..0000000 --- a/scripts/tracediff.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -########################################################################## -# -# Copyright 2011 Jose Fonseca -# All Rights Reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -##########################################################################/ - -set -e - -APITRACE=${APITRACE:-apitrace} - -$APITRACE dump - -stripdump () { - $APITRACE dump --color=never --arg-names=no "$1" \ - | sed \ - -e 's/\r$//g' \ - -e 's/^[0-9]\+ //' \ - -e 's/hdc = \w\+/hdc/g' \ - | head -1000 \ - > "$2" -} - -FIFODIR=`mktemp -d` -FIFO1="$FIFODIR/1" -FIFO2="$FIFODIR/2" - -mkfifo "$FIFO1" -mkfifo "$FIFO2" - -stripdump "$1" "$FIFO1" & -stripdump "$2" "$FIFO2" & - -sdiff \ - --width=`tput cols` \ - --speed-large-files \ - "$FIFO1" "$FIFO2" \ -| less -R - -rm -rf "$FIFODIR" -- 2.43.0