This adds: * zip_lists: Pair elements from two lists. * get_argtypes: Get the list of types of the arguments; can optionally transform the types in the process.
The function 'get_args' is modified to use a combination of 'get_argnames', 'get_argtypes', 'zip_lists' and, optionally, use the type transformation capabilities of 'get_argtypes'. Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- scripts/tracetool | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 116 insertions(+), 1 deletions(-) diff --git a/scripts/tracetool b/scripts/tracetool index 4c9951d..f2b6680 100755 --- a/scripts/tracetool +++ b/scripts/tracetool @@ -74,15 +74,130 @@ has_property() return 1 } +# Convenience function to pair elements from two comma-separated lists of equal +# size. +# 1: first list +# 2: second list +# 3: printf format for each pair of elements (optional, default: "%s %s, ") +zip_lists() +{ + [ -n "$1" -a -n "$2" ] || return + + local format + format=$3 + [ -n "$format" ] || format="%s %s, " + + local i elem accum + i=1 + accum="" + for elem in $1; do + if [ "$elem" = "${elem%,}" ]; then + accum="$accum $elem" + else + accum="$accum ${elem%,}" + eval __elem_$i=\"$accum\" + i=$(($i + 1)) + accum="" + fi + done + eval __elem_$i=\"$accum\" + + local tmp res + accum="" + res="" + i=1 + for elem in $2; do + if [ "$elem" = "${elem%,}" ]; then + accum="$accum $elem" + else + accum="$accum ${elem%,}" + eval tmp=\$__elem_$i + tmp=$(printf "$format" "$tmp" "$accum") + res="$res$tmp" + i=$(($i + 1)) + accum="" + fi + done + eval tmp=\$__elem_$i + tmp=$(printf "$format" "$tmp" "$accum") + res="$res$tmp" + res="${res%, }" + echo $res +} + # Get the argument list of a trace event, including types and names +# 1: event name +# 2: passed as the second argument to 'get_argtypes' (optional) get_args() { local args args=${1#*\(} args=${args%%\)*} - echo "$args" + + if [ -z "$2" -o "$args" = "void" ]; then + echo "$args" + else + local argtypes argnames res + argtypes=$(get_argtypes "$1" $2) + argnames=$(get_argnames "$1" ",") + res=$(zip_lists "$argtypes" "$argnames") + echo "${res#, }" + fi } +# Get the argument type list of a trace event +# 1: event name +# 2: function to translate each of the types (optional, default: nil_type) +get_argtypes() +{ + local translate field type res + + translate=$2 + [ -n "$translate" ] || translate=nil_type + + res="" + type="" + for field in $(get_args "$1"); do + if [ "${field%,}" != "${field}" ]; then + # it's a name, but can have a star in it + [ "${field#\*}" = "$field" ] || type="${type}*" + # trim spaces + type="${type## }" + type="${type%% }" + # translate + type=$($translate "$type") + res="$res$type, " + type="" + else + # types can have spaces + type="$type $field" + fi + done + + # remove the accumulated name + field="${type##* }" + type="${type% *}" + + # trim spaces + type="${type## }" + type="${type%% }" + + # it's a name, but can have a star in it + [ "${field#\*}" = "$field" ] || type="${type}*" + # translate + type=$($translate "$type") + res="$res$type" + + echo $res +} + +# No-op type translator for get_argtypes +nil_type() +{ + echo "$1" +} + + # Get the argument name list of a trace event get_argnames() {