options »rows« added, calculations in value-fields
This commit is contained in:
parent
be7078f82a
commit
926e95143c
143
protocol
143
protocol
|
@ -56,7 +56,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# STANDARD LIBRARY IMPORTS
|
# STANDARD LIBRARY IMPORTS
|
||||||
import sys
|
import sys, re
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
# INTERNAL IMPORTS
|
# INTERNAL IMPORTS
|
||||||
|
@ -88,17 +88,18 @@ class Protocol():
|
||||||
Class constructor.
|
Class constructor.
|
||||||
@param spec is the textual specification that describes the protocol.
|
@param spec is the textual specification that describes the protocol.
|
||||||
"""
|
"""
|
||||||
self.hdr_char_start="+" # Character for start of the border line
|
self.hdr_char_start = "+" # Character for start of the border line
|
||||||
self.hdr_char_end="+" # Character for end of the border line
|
self.hdr_char_end = "+" # Character for end of the border line
|
||||||
self.hdr_char_fill_odd="+" # Fill character for border odd positions
|
self.hdr_char_fill_odd = "+" # Fill character for border odd positions
|
||||||
self.hdr_char_fill_even="-" # Fill character for border even positions
|
self.hdr_char_fill_even = "-" # Fill character for border even positions
|
||||||
self.hdr_char_sep="|" # Field separator character
|
self.hdr_char_sep = "|" # Field separator character
|
||||||
self.bits_per_line=32 # Number of bits per line
|
self.bits_per_line = 32 # Number of bits per line
|
||||||
self.base_of_top_tens=10 # Base of top numbers
|
self.base_of_top_tens = 10 # Base of top numbers
|
||||||
self.do_print_top_tens=True # True: print top numbers for bit tens
|
self.do_print_top_tens = True # True: print top numbers for bit tens
|
||||||
self.do_print_top_units=True # True: print top numbers for bit units
|
self.do_print_top_units = True # True: print top numbers for bit units
|
||||||
self.field_list=[] # Header fields to be printed out
|
self.do_print_line_number = 0 # >0: print line numbers on left side
|
||||||
self.parse_spec(spec) # Parse the received spec and populate self.field_list
|
self.field_list = [] # Header fields to be printed out
|
||||||
|
self.parse_spec(spec) # Parse the received spec and populate self.field_list
|
||||||
|
|
||||||
|
|
||||||
def parse_spec(self, spec):
|
def parse_spec(self, spec):
|
||||||
|
@ -120,19 +121,44 @@ class Protocol():
|
||||||
fields=spec
|
fields=spec
|
||||||
opts=None
|
opts=None
|
||||||
|
|
||||||
# Parse field spec
|
|
||||||
items=fields.split(",")
|
items=fields.split(",")
|
||||||
for item in items:
|
for item in items:
|
||||||
try:
|
try:
|
||||||
text, bits = item.split(":")
|
parts = item.split(":")
|
||||||
bits=int(bits)
|
if len(parts)==1:
|
||||||
if bits<=0:
|
if item in specs.protocols:
|
||||||
raise ProtocolException("FATAL: Fields must be at least one bit long (%s)" %spec)
|
self.parse_spec(specs.protocols[item])
|
||||||
|
else:
|
||||||
|
start_with_the_same=[]
|
||||||
|
for spec in specs.protocols:
|
||||||
|
if spec.startswith(item):
|
||||||
|
start_with_the_same.append(spec)
|
||||||
|
if len(start_with_the_same)==1:
|
||||||
|
self.parse_spec(specs.protocols[start_with_the_same[0]])
|
||||||
|
elif len(start_with_the_same)==0:
|
||||||
|
raise ProtocolException("FATAL: neither does supplied protocol '%s' exist nor does any known protocol start with that." % item)
|
||||||
|
else:
|
||||||
|
fail = "Ambiguous protocol specifier '%s'. Did you mean any of these?" % item
|
||||||
|
for spec in start_with_the_same:
|
||||||
|
fail += "\n %s" % spec
|
||||||
|
raise ProtocolException(fail)
|
||||||
|
else:
|
||||||
|
text = parts[0]
|
||||||
|
for item in range(1, len(parts)-1):
|
||||||
|
text += ":" + parts[item]
|
||||||
|
bits = parts[-1]
|
||||||
|
bits = bits.replace("bytes", "8").replace("qwords", "64").replace("dwords", "32").replace("words", "16").replace("double", "64").replace("floats", "32")
|
||||||
|
if re.match("^[0-9+-/\*~|&^<>()]+$", bits):
|
||||||
|
bits=eval(bits)
|
||||||
|
if bits<=0:
|
||||||
|
raise ProtocolException("FATAL: Fields must be at least one bit long (%s)" % spec)
|
||||||
|
else:
|
||||||
|
raise ProtocolException("FATAL: invalid number of bits (%s)" % bits)
|
||||||
|
self.field_list.append({"text":text, "len":bits})
|
||||||
except ProtocolException:
|
except ProtocolException:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
raise ProtocolException("FATAL: Invalid field_list specification (%s)" %spec)
|
raise ProtocolException("FATAL: Invalid field_list specification (%s)" % spec)
|
||||||
self.field_list.append({"text":text, "len":bits})
|
|
||||||
|
|
||||||
# Parse options
|
# Parse options
|
||||||
if opts is not None:
|
if opts is not None:
|
||||||
|
@ -141,13 +167,23 @@ class Protocol():
|
||||||
try:
|
try:
|
||||||
var, value = opt.replace(':','=').split("=")
|
var, value = opt.replace(':','=').split("=")
|
||||||
if var.lower()=="bits":
|
if var.lower()=="bits":
|
||||||
self.bits_per_line=int(value)
|
value = value.replace("bytes", "8").replace("qwords", "64").replace("dwords", "32").replace("words", "16").replace("double", "64").replace("floats", "32")
|
||||||
if self.bits_per_line<=0:
|
if re.match("^[0-9+-/\*~|&^<>()]+$", value):
|
||||||
|
self.bits_per_line=eval(value)
|
||||||
|
if self.bits_per_line<=0:
|
||||||
raise ProtocolException("FATAL: Invalid value for 'bits' option (%s)" % value)
|
raise ProtocolException("FATAL: Invalid value for 'bits' option (%s)" % value)
|
||||||
|
else:
|
||||||
|
raise ProtocolException("FATAL: invalid number of bits (%s)" % value)
|
||||||
elif var.lower()=="base":
|
elif var.lower()=="base":
|
||||||
self.base_of_top_tens=int(value)
|
self.base_of_top_tens=int(value)
|
||||||
if self.base_of_top_tens<=0 or self.base_of_top_tens>16:
|
if self.base_of_top_tens<=0 or self.base_of_top_tens>16:
|
||||||
raise ProtocolException("FATAL: Invalid value for 'base' option (%s)" % value)
|
raise ProtocolException("FATAL: Invalid value for 'base' option (%s)" % value)
|
||||||
|
elif var.lower()=="rows":
|
||||||
|
self.do_print_line_number=int(value)
|
||||||
|
if self.do_print_line_number<0:
|
||||||
|
raise ProtocolException("FATAL: Invalid value for 'rows' option (%s)" % value)
|
||||||
|
if self.do_print_line_number > 0:
|
||||||
|
self.do_print_line_number += 1
|
||||||
elif var.lower()=="numbers":
|
elif var.lower()=="numbers":
|
||||||
if value.lower() in ["0", "n", "no", "none", "false"]:
|
if value.lower() in ["0", "n", "no", "none", "false"]:
|
||||||
self.do_print_top_tens=False
|
self.do_print_top_tens=False
|
||||||
|
@ -189,17 +225,18 @@ class Protocol():
|
||||||
"""
|
"""
|
||||||
lines=["", ""]
|
lines=["", ""]
|
||||||
chars="0123456789abcdef"
|
chars="0123456789abcdef"
|
||||||
|
lines[0]+=" "*self.do_print_line_number
|
||||||
if self.do_print_top_tens is True:
|
if self.do_print_top_tens is True:
|
||||||
for i in range(0, self.bits_per_line):
|
for i in range(0, self.bits_per_line):
|
||||||
if i%self.base_of_top_tens==0:
|
if i%self.base_of_top_tens == 0:
|
||||||
lines[0]+=" %s" % chars[int(i/self.base_of_top_tens)%self.base_of_top_tens]
|
lines[0]+=" %s" % chars[int(i/self.base_of_top_tens)%self.base_of_top_tens]
|
||||||
else:
|
else:
|
||||||
lines[0]+=" "
|
lines[0]+=" "
|
||||||
lines[0]+="\n"
|
lines[0]+="\n"
|
||||||
|
lines[0]+=" "*self.do_print_line_number
|
||||||
if self.do_print_top_units is True:
|
if self.do_print_top_units is True:
|
||||||
for i in range(0, self.bits_per_line):
|
for i in range(0, self.bits_per_line):
|
||||||
lines[1]+=" %s" % chars[i%self.base_of_top_tens]
|
lines[1]+=" %s" % chars[i%self.base_of_top_tens]
|
||||||
#lines[1]+="\n"
|
|
||||||
result = "".join(lines)
|
result = "".join(lines)
|
||||||
return result if len(result)>0 else None
|
return result if len(result)>0 else None
|
||||||
|
|
||||||
|
@ -216,9 +253,9 @@ class Protocol():
|
||||||
if width<=0:
|
if width<=0:
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
a="%s" % self.hdr_char_start
|
a = "%s" % self.hdr_char_start
|
||||||
b=(self.hdr_char_fill_even+self.hdr_char_fill_odd)*(width-1)
|
b = (self.hdr_char_fill_even+self.hdr_char_fill_odd)*(width-1)
|
||||||
c="%s%s" % (self.hdr_char_fill_even, self.hdr_char_end)
|
c = "%s%s" % (self.hdr_char_fill_even, self.hdr_char_end)
|
||||||
return a+b+c
|
return a+b+c
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,13 +347,14 @@ class Protocol():
|
||||||
numbers=self._get_top_numbers()
|
numbers=self._get_top_numbers()
|
||||||
if numbers is not None:
|
if numbers is not None:
|
||||||
lines.append(numbers)
|
lines.append(numbers)
|
||||||
lines.append(self._get_horizontal())
|
lines.append(" "*self.do_print_line_number+self._get_horizontal())
|
||||||
|
|
||||||
# Print all protocol fields
|
# Print all protocol fields
|
||||||
bits_in_line=0
|
bits_in_line=0
|
||||||
current_line=""
|
current_line=""
|
||||||
fields_done=0
|
fields_done=0
|
||||||
p=-1
|
p=-1
|
||||||
|
line_number=0
|
||||||
while p < len(proto_fields)-1:
|
while p < len(proto_fields)-1:
|
||||||
p+=1
|
p+=1
|
||||||
|
|
||||||
|
@ -339,7 +377,10 @@ class Protocol():
|
||||||
# If this is the first thing we print on a line, add the
|
# If this is the first thing we print on a line, add the
|
||||||
# starting character
|
# starting character
|
||||||
if bits_in_line==0:
|
if bits_in_line==0:
|
||||||
current_line+=self._get_separator()
|
if self.do_print_line_number:
|
||||||
|
current_line+=str(line_number).rjust(self.do_print_line_number-1)+" "
|
||||||
|
line_number+=1
|
||||||
|
current_line+=self._get_separator()
|
||||||
|
|
||||||
# Add the whole field
|
# Add the whole field
|
||||||
current_line+=str.center(field_text, (field_len*2)-1)
|
current_line+=str.center(field_text, (field_len*2)-1)
|
||||||
|
@ -369,6 +410,7 @@ class Protocol():
|
||||||
line_left=self._get_horizontal(self.bits_per_line - field_len)
|
line_left=self._get_horizontal(self.bits_per_line - field_len)
|
||||||
if len(line_left)==0:
|
if len(line_left)==0:
|
||||||
line_left=self.hdr_char_start
|
line_left=self.hdr_char_start
|
||||||
|
line_left=" "*self.do_print_line_number+line_left
|
||||||
|
|
||||||
# Now print some empty space to cover the part that
|
# Now print some empty space to cover the part that
|
||||||
# we can join with the field below.
|
# we can join with the field below.
|
||||||
|
@ -389,7 +431,7 @@ class Protocol():
|
||||||
else:
|
else:
|
||||||
lines.append(self._get_horizontal())
|
lines.append(self._get_horizontal())
|
||||||
else:
|
else:
|
||||||
lines.append(self._get_horizontal())
|
lines.append(" "*self.do_print_line_number+self._get_horizontal())
|
||||||
|
|
||||||
|
|
||||||
# If this is not the last character of the line but we have no
|
# If this is not the last character of the line but we have no
|
||||||
|
@ -420,10 +462,11 @@ class Protocol():
|
||||||
# Let's figure out which character we need to use
|
# Let's figure out which character we need to use
|
||||||
# to start and end the current line
|
# to start and end the current line
|
||||||
if i%2==1:
|
if i%2==1:
|
||||||
start_line=self.hdr_char_start
|
start_line=" "*self.do_print_line_number+self.hdr_char_start
|
||||||
end_line=self.hdr_char_end
|
end_line=self.hdr_char_end
|
||||||
else:
|
else:
|
||||||
start_line=self.hdr_char_sep
|
start_line=str(line_number).rjust(self.do_print_line_number-1)+" "+self.hdr_char_sep
|
||||||
|
line_number+=1
|
||||||
end_line=self.hdr_char_sep
|
end_line=self.hdr_char_sep
|
||||||
|
|
||||||
# This is the line where we need to print the field
|
# This is the line where we need to print the field
|
||||||
|
@ -435,7 +478,7 @@ class Protocol():
|
||||||
lines.append(start_line + (" " * ((self.bits_per_line*2)-1)) + end_line)
|
lines.append(start_line + (" " * ((self.bits_per_line*2)-1)) + end_line)
|
||||||
# If we just added the last line, add a horizontal separator
|
# If we just added the last line, add a horizontal separator
|
||||||
if i==lines_to_print-1:
|
if i==lines_to_print-1:
|
||||||
lines.append(self._get_horizontal())
|
lines.append(" "*self.do_print_line_number+self._get_horizontal())
|
||||||
|
|
||||||
# Case 2: We are not at the beginning of the line and we need
|
# Case 2: We are not at the beginning of the line and we need
|
||||||
# to print something that does not fit in the current line
|
# to print something that does not fit in the current line
|
||||||
|
@ -637,46 +680,12 @@ class Main():
|
||||||
|
|
||||||
# Protocol name or protocol spec
|
# Protocol name or protocol spec
|
||||||
else:
|
else:
|
||||||
# If it contains ":" characters, we have a protocol spec
|
|
||||||
if argv[i].count(":")>0:
|
|
||||||
spec = argv[i]
|
|
||||||
# Otherwise, the user meant to display an existing protocol
|
|
||||||
else:
|
|
||||||
# If we got an exact match, end of story
|
|
||||||
if argv[i] in specs.protocols:
|
|
||||||
spec = specs.protocols[argv[i]]
|
|
||||||
# Otherwise, we may have received a partial match so
|
|
||||||
# we need to figure out which protocol the user meant.
|
|
||||||
# If the specification is ambiguous, we will error
|
|
||||||
else:
|
|
||||||
start_with_the_same=[]
|
|
||||||
for spec in specs.protocols:
|
|
||||||
if spec.startswith(argv[i]):
|
|
||||||
start_with_the_same.append(spec)
|
|
||||||
# If we only have one entry, it means we got some
|
|
||||||
# shortened version of the protocol name but no
|
|
||||||
# ambiguity. In that case, we will use the match.
|
|
||||||
if len(start_with_the_same)==1:
|
|
||||||
spec=specs.protocols[start_with_the_same[0]]
|
|
||||||
elif len(start_with_the_same)==0:
|
|
||||||
print("ERROR: supplied protocol '%s' does not exist." % argv[i]);
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
print("Ambiguous protocol specifier '%s'. Did you mean any of these?" % argv[i])
|
|
||||||
for spec in start_with_the_same:
|
|
||||||
print(" %s" % spec)
|
|
||||||
sys.exit(1)
|
|
||||||
# Finally, based on the spec, instance an actual protocol.
|
|
||||||
# Note that if the spec is incorect, the Protocol() consutrctor
|
|
||||||
# will call sys.exit() itself, so there is no need to do
|
|
||||||
# error checking here.
|
|
||||||
try:
|
try:
|
||||||
proto = Protocol(spec)
|
proto = Protocol(argv[i])
|
||||||
self.protocols.append(proto)
|
self.protocols.append(proto)
|
||||||
except ProtocolException as e:
|
except ProtocolException as e:
|
||||||
print("ERROR: %s" % str(e))
|
print("ERROR: %s" % str(e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(self.protocols)==0:
|
if len(self.protocols)==0:
|
||||||
print("ERROR: Missing protocol")
|
print("ERROR: Missing protocol")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user