Rich man's profiler - handling quotes

This commit is contained in:
Pavel Kirienko
2015-01-17 02:58:07 +03:00
committed by Lorenz Meier
parent d1abf9c133
commit f158c8270b
+31 -18
View File
@@ -122,13 +122,12 @@ fi
# #
[ -f $stacksfile ] || die "Where are the stack samples?" [ -f $stacksfile ] || die "Where are the stack samples?"
cat $stacksfile | python -c " cat << 'EOF' > /tmp/pmpn-folder.py
# #
# This stack folder correctly handles C++ types. # This stack folder correctly handles C++ types.
# #
from __future__ import print_function, division from __future__ import print_function, division
import fileinput, collections, os import fileinput, collections, os, sys
def enforce(x, msg='Invalid input'): def enforce(x, msg='Invalid input'):
if not x: if not x:
@@ -137,20 +136,29 @@ def enforce(x, msg='Invalid input'):
def split_first_part_with_parens(line): def split_first_part_with_parens(line):
LBRACES = {'(':'()', '<':'<>', '[':'[]', '{':'{}'} LBRACES = {'(':'()', '<':'<>', '[':'[]', '{':'{}'}
RBRACES = {')':'()', '>':'<>', ']':'[]', '}':'{}'} RBRACES = {')':'()', '>':'<>', ']':'[]', '}':'{}'}
QUOTES = set(['"', "'"])
quotes = collections.defaultdict(bool)
braces = collections.defaultdict(int) braces = collections.defaultdict(int)
out = '' out = ''
for ch in line: for ch in line:
out += ch out += ch
# escape character cancels further processing
if ch == '\\':
continue
# special cases # special cases
if out.endswith('operator>') or out.endswith('operator->'): # gotta love c++ if out.endswith('operator>') or out.endswith('operator->'): # gotta love c++
braces['<>'] += 1 braces['<>'] += 1
if out.endswith('operator<'): if out.endswith('operator<'):
braces['<>'] -= 1 braces['<>'] -= 1
# counting parens # switching quotes
if ch in LBRACES.keys(): if ch in QUOTES:
braces[LBRACES[ch]] += 1 quotes[ch] = not quotes[ch]
if ch in RBRACES.keys(): # counting parens only when outside quotes
braces[RBRACES[ch]] -= 1 if sum(quotes.values()) == 0:
if ch in LBRACES.keys():
braces[LBRACES[ch]] += 1
if ch in RBRACES.keys():
braces[RBRACES[ch]] -= 1
# sanity check # sanity check
for v in braces.values(): for v in braces.values():
enforce(v >= 0, 'Unaligned braces: ' + str(dict(braces))) enforce(v >= 0, 'Unaligned braces: ' + str(dict(braces)))
@@ -206,19 +214,24 @@ def parse(line):
stacks = collections.defaultdict(int) stacks = collections.defaultdict(int)
current = '' current = ''
for line in fileinput.input(): for idx,line in enumerate(fileinput.input()):
line = line.strip() try:
if line: line = line.strip()
inf = parse(line) if line:
fun = inf['function'] inf = parse(line)
current = (fun + ';' + current) if current else fun fun = inf['function']
elif current: current = (fun + ';' + current) if current else fun
stacks[current] += 1 elif current:
current = '' stacks[current] += 1
current = ''
except Exception, ex:
print('ERROR (line %d):' % (idx + 1), ex, file=sys.stderr)
for s, f in sorted(stacks.items(), key=lambda (s, f): s): for s, f in sorted(stacks.items(), key=lambda (s, f): s):
print(s, f) print(s, f)
" > $foldfile EOF
cat $stacksfile | python /tmp/pmpn-folder.py > $foldfile
echo "Folded stacks saved to $foldfile" echo "Folded stacks saved to $foldfile"