Commit 11438b8c authored by Per Cederqvist's avatar Per Cederqvist
Browse files

Generate protocol-a-recommended.txt and protocol-a-current.txt.

(prot_a_type.__init__): Initialize __recommended to 0.
(prot_a_type.use): New argument: recommended.  All callers
	updated.  Set the __recommended flag once a recommended
	request or async uses this type.
(prot_a_builtin.use_recurse): Ditto.
(prot_a_type.recommended): New method.
(lexer.__parse_type): Replaced the protover arguemnt with a
	request object.  All callers updated.
(lexer.__parse_request_arg): Ditto.
(generate_stable_output): New argument: filename,
	only_recommended.
(generate_summary_output): New function.
parent 4c3ca617
......@@ -155,13 +155,14 @@ class prot_a_type:
"""
self.__line = line
self.__protover = None
self.__recommended = 0
def line_no(self):
"""Return the line number that defined this type.
"""
return self.__line
def use(self, protover):
def use(self, protover, recommended):
"""Mark this type as used by something else.
This will increase the usage count (returned by usage())
......@@ -171,12 +172,17 @@ class prot_a_type:
PROTOVER is the version of the request or async message that
uses this type. The type will remember the lowest PROTOVER;
this is the protocol version where the type was introduced.
RECOMMENDED is true if this is used by a Recommended request
or async message.
"""
self.__usage_count = self.__usage_count + 1
if self.__protover == None or protover < self.__protover:
self.__protover = protover
if self.__usage_count == 1:
self.use_recurse(protover)
self.use_recurse(protover, recommended)
if recommended:
self.__recommended = 1
def usage(self):
"""Return the usage count.
......@@ -188,10 +194,15 @@ class prot_a_type:
"""
return self.__protover
def recommended(self):
"""Return true if this type is used by a recommended request or async.
"""
return self.__recommended
class prot_a_builtin(prot_a_type):
"""Basic types defined by the protocol, such as INT32.
"""
def use_recurse(self, protover):
def use_recurse(self, protover, recommended):
pass
class prot_a_simple(prot_a_type):
......@@ -202,8 +213,8 @@ class prot_a_simple(prot_a_type):
self.__array = is_array
prot_a_type.__init__(self, line)
def use_recurse(self, protover):
defined_types[self.__type].use(protover)
def use_recurse(self, protover, recommended):
defined_types[self.__type].use(protover, recommended)
def base_type(self):
return self.__type
......@@ -220,9 +231,9 @@ class prot_a_alternate(prot_a_type):
self.__type_b = type_b
prot_a_type.__init__(self, line)
def use_recurse(self, protover):
defined_types[self.__type_a].use(protover)
defined_types[self.__type_b].use(protover)
def use_recurse(self, protover, recommended):
defined_types[self.__type_a].use(protover, recommended)
defined_types[self.__type_b].use(protover, recommended)
def type_a(self):
return self.__type_a
......@@ -252,9 +263,9 @@ class prot_a_struct(prot_a_type):
del undefined_fields[field_name]
return None
def use_recurse(self, protover):
def use_recurse(self, protover, recommended):
for (fn, tn, ar) in self.__fields:
defined_types[tn].use(protover)
defined_types[tn].use(protover, recommended)
def fields(self):
return self.__fields
......@@ -289,7 +300,7 @@ class prot_a_bitstring(prot_a_type):
res.append("%s: bit ``%s'' not implemented" % (name, f))
return res
def use_recurse(self, protover):
def use_recurse(self, protover, recommended):
pass
def bits(self):
......@@ -329,9 +340,9 @@ class prot_a_selection(prot_a_type):
def all_names(self):
return self.__used_names.keys()
def use_recurse(self, protover):
def use_recurse(self, protover, recommended):
for (number, name, tailname, tail_type, is_array) in self.__fields:
defined_types[tail_type].use(protover)
defined_types[tail_type].use(protover, recommended)
def fields(self):
return self.__fields
......@@ -343,8 +354,8 @@ class prot_a_enumeration_of(prot_a_type):
prot_a_type.__init__(self, line)
self.__base = base
def use_recurse(self, protover):
defined_types[self.__base].use(protover)
def use_recurse(self, protover, recommended):
defined_types[self.__base].use(protover, recommended)
def base_type(self):
return self.__base
......@@ -989,7 +1000,6 @@ class lexer:
self.error(line_no, "...clashing")
def __parse_async(self, req):
protover = req.protover()
self.__tokens = []
async = self.__get_token()
if async != self.__amindex:
......@@ -1027,17 +1037,17 @@ class lexer:
next = self.__get_token()
if next != ')':
self.__unget_token(next)
req.append_arg(self.__parse_request_arg(protover))
req.append_arg(self.__parse_request_arg(req))
next = self.__get_token()
if next != ')':
self.error(self.__reader.line_no(),
"missing close parenthesis after arguments")
return
elif paren == '((':
req.append_arg(self.__parse_request_arg(protover))
req.append_arg(self.__parse_request_arg(req))
next = self.__get_token()
while next == ';':
req.append_arg(self.__parse_request_arg(protover))
req.append_arg(self.__parse_request_arg(req))
next = self.__get_token()
if next != '))':
self.error(self.__reader.line_no(),
......@@ -1379,7 +1389,6 @@ class lexer:
return prot_a_enumeration_of(line, name)
def __parse_request(self, req_obj):
protover = req_obj.protover()
self.__tokens = []
req = self.__get_token()
if req != self.__findex:
......@@ -1417,17 +1426,17 @@ class lexer:
next = self.__get_token()
if next != ')':
self.__unget_token(next)
req_obj.append_arg(self.__parse_request_arg(protover))
req_obj.append_arg(self.__parse_request_arg(req_obj))
next = self.__get_token()
if next != ')':
self.error(self.__reader.line_no(),
"missing close parenthesis after arguments")
return
elif paren == '((':
req_obj.append_arg(self.__parse_request_arg(protover))
req_obj.append_arg(self.__parse_request_arg(req_obj))
next = self.__get_token()
while next == ';':
req_obj.append_arg(self.__parse_request_arg(protover))
req_obj.append_arg(self.__parse_request_arg(req_obj))
next = self.__get_token()
if next != '))':
self.error(self.__reader.line_no(),
......@@ -1449,7 +1458,7 @@ class lexer:
next = self.__get_token()
if next != ')':
self.__unget_token(next)
(ret_type, ret_array) = self.__parse_type(protover)
(ret_type, ret_array) = self.__parse_type(req_obj)
req_obj.set_return_type(ret_type, ret_array)
next = self.__get_token()
if next != ')':
......@@ -1466,7 +1475,7 @@ class lexer:
return
def __parse_type(self, protover):
def __parse_type(self, req_obj):
token = self.__get_lt_token()
if token == 'ARRAY':
token = self.__get_lt_token()
......@@ -1478,7 +1487,7 @@ class lexer:
if not defined_types.has_key(token):
self.error(self.__reader.line_no(),
"undefined type ``%s''" % token)
defined_types[token].use(protover)
defined_types[token].use(req_obj.protover(), req_obj.recommended())
return (token, array)
def __get_lt_token(self):
......@@ -1562,14 +1571,14 @@ class lexer:
"bad argument ``%s''" % (arg,))
return not ok
def __parse_request_arg(self, protover):
def __parse_request_arg(self, req_obj):
argname = self.__get_token()
if self.__bad_arg(argname):
return
if self.__get_token() != ':':
self.error(self.__reader.line_no(), "missing ``:'' after argument")
return
(tp, array) = self.__parse_type(protover)
(tp, array) = self.__parse_type(req_obj)
if tp == None:
return
if self.__args.has_key(argname):
......@@ -1773,8 +1782,8 @@ class lexer:
at[async_name] = stable
ar[stable] = async_name
def generate_stable_output():
fp = open("protocol-a.txt.tmp", "w")
def generate_stable_output(filename, only_recommended):
fp = open(filename + ".tmp", "w")
fp.write("# This protocol-a.txt, generated from Protocol-A.texi\n")
fp.write("# by checkargs.py. This file contains the definitions\n")
fp.write("# of the types, requests and asynchronous messages in a\n")
......@@ -1789,6 +1798,9 @@ def generate_stable_output():
fp.write("# stabilized a future version of the file will probably\n")
fp.write("# be placed in the public domain.\n")
fp.write("\n")
if only_recommended:
fp.write("# This file only contains the recommended stuff.\n")
else:
fp.write("# Note: this file does not describe request 12,\n")
fp.write("# lookup-name, which returns Conf-List-Archaic.\n")
fp.write("# That is because that data type is so irregular.\n")
......@@ -1810,6 +1822,8 @@ def generate_stable_output():
tlist.sort()
for tn in tlist:
if only_recommended and not defined_types[tn].recommended():
continue
if tn != tt[tn] and tn not in ["Conf-List-Archaic"]:
fp.write("%%type-alias %-30s %s\n" % (tt[tn], tn))
......@@ -1820,6 +1834,9 @@ def generate_stable_output():
rlist.sort()
for rn in rlist:
if (only_recommended
and not defined_request_names[rn].recommended()):
continue
if rn != rt[rn] and rn not in ["lookup-name-1"]:
fp.write("%%request-alias %-30s %s\n" % (rt[rn], rn))
......@@ -1830,6 +1847,9 @@ def generate_stable_output():
alist.sort()
for an in alist:
if (only_recommended
and not defined_async_names[an].recommended()):
continue
if an != at[an]:
fp.write("%%async-alias %-30s %s\n" % (at[an], an))
......@@ -1844,6 +1864,8 @@ def generate_stable_output():
if tn in ["Conf-List-Archaic-1"]:
continue
t = defined_types[tr[tn]]
if only_recommended and not t.recommended():
continue
if isinstance(t, prot_a_builtin):
fp.write("%%builtin %s\n" % tn)
elif isinstance(t, prot_a_simple):
......@@ -1914,6 +1936,8 @@ def generate_stable_output():
if rn in ["lookup-name-1"]:
continue
r = defined_request_names[rr[rn]]
if only_recommended and not r.recommended():
continue
fp.write("%%Request: %d\n" % r.request_nr())
fp.write(" %%Name: %s\n" % rt[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover())
......@@ -1970,6 +1994,8 @@ def generate_stable_output():
for an in alist:
r = defined_async_names[ar[an]]
if only_recommended and not r.recommended():
continue
fp.write("%%Async: %d\n" % r.request_nr())
fp.write(" %%Async-Name: %s\n" % at[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover())
......@@ -2013,13 +2039,209 @@ def generate_stable_output():
fp.write("\n\n")
fp.close()
os.rename("protocol-a.txt.tmp", "protocol-a.txt")
os.rename(filename + ".tmp", filename)
def generate_summary_output(filename):
fp = open(filename + ".tmp", "w")
fp.write("# This is %s, generated from Protocol-A.texi\n" % filename)
fp.write("# by checkargs.py. This file contains the definitions\n")
fp.write("# of the types, requests and asynchronous messages in a\n")
fp.write("# format that is intended to be both machine-readable and\n")
fp.write("# human-readable. The requess may be renamed in the future.\n")
fp.write("\n")
fp.write("# This file is Copyright (C) 1995-2003 Lysator ACS.\n")
fp.write("# All rights reserved. This file may only be used\n")
fp.write("# for testing purposes. Once the file format has\n")
fp.write("# stabilized a future version of the file will probably\n")
fp.write("# be placed in the public domain.\n")
fp.write("\n")
fp.write("# This file only contains the recommended stuff.\n")
fp.write("\n")
fp.write("%%PROTOEDITION %s\n" % set_values["PROTOEDITION"])
fp.write("%%PROTOVER %s\n" % set_values["PROTOVER"])
fp.write("%%LYSKOMDVERSION %s\n\n" % set_values["VERSION"])
tlist = tt.keys()
tlist.sort()
for tn in tlist:
t = defined_types[tn]
if not t.recommended():
continue
if isinstance(t, prot_a_builtin):
fp.write("%%builtin %s\n" % tn)
elif isinstance(t, prot_a_simple):
if t.array():
fp.write("%s ::= ARRAY %s\n" % (tn, t.base_type()))
else:
fp.write("%s ::= %s\n" % (tn, t.base_type()))
elif isinstance(t, prot_a_alternate):
fp.write("%s ::= %s | %s\n" % (tn,
t.type_a(),
t.type_b()))
elif isinstance(t, prot_a_struct):
fp.write("%s ::=\n" % tn)
first = 1
for field_name, field_type, is_array in t.fields():
if first:
fp.write(" ( ")
else:
fp.write(" ")
first = 0
if is_array:
fp.write("%-20s : ARRAY %s;\n" % (field_name,
field_type))
else:
fp.write("%-20s : %s;\n" % (field_name,
field_type))
fp.write(" )\n")
elif isinstance(t, prot_a_bitstring):
fp.write("%s ::= BITSTRING\n" % tn)
first = 1
for bit in t.bits():
if first:
fp.write(" ( ")
else:
fp.write(" ")
first = 0
fp.write("%s;\n" % bit)
fp.write(" )\n")
elif isinstance(t, prot_a_selection):
fp.write("%s ::= SELECTION\n" % tn)
first = 1
for (nr, name, tailname, tailtype, array) in t.fields():
if first:
fp.write(" ( ")
else:
fp.write(" ")
first = 0
fp.write("%2d=%-10s %-20s : " % (nr, name, tailname))
if array:
fp.write("ARRAY ")
fp.write("%s;\n" % tailtype)
fp.write(" )\n")
elif isinstance(t, prot_a_enumeration_of):
fp.write("%s ::= ENUMERATION-OF(%s)\n" % (
tn, t.base_type()))
else:
sys.stderr.write("bad type %s" % repr(t))
sys.exit(1)
rlist = rt.keys()
rlist.sort()
for rn in rlist:
r = defined_request_names[rn]
if not r.recommended():
continue
fp.write("%%Request: %d\n" % r.request_nr())
fp.write(" %%Name: %s\n" % r.request_name())
fp.write(" %%Stable-Name: %s\n" % rt[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover())
if r.recommended():
fp.write(" %Status: Recommended\n")
elif r.experimental():
fp.write(" %Status: Experimental\n")
elif r.obsolete():
fp.write(" %Status: Obsolete\n")
fp.write(" %%Obsoleted by: %s\n" % r.obsver())
else:
sys.stderr.write("No status found\n")
sys.exit(1)
fp.write("%End Request\n\n")
leader = "%s [%d]" % (r.request_name(), r.request_nr())
if len(r.arguments()) == 0:
fp.write("%s ( )" % (leader))
elif len(r.arguments()) == 1 and r.arguments()[0] != None:
argname, argtype, array = r.arguments()[0]
if array:
fp.write("%s ( %s : ARRAY %s )" % (leader,
argname, argtype))
else:
fp.write("%s ( %s : %s )" % (leader, argname, argtype))
else:
leader = "%s (( " % leader
fp.write(leader)
first = 1
for a in r.arguments():
if a == None:
continue
argname, argtype, array = a
if not first:
fp.write(";\n" + " " * len(leader))
if array:
fp.write("%-10s : ARRAY %s" % (argname, argtype))
else:
fp.write("%-10s : %s" % (argname, argtype))
first = 0
fp.write(" ))")
fp.write("\n -> ( ")
if r.return_type() != None:
if r.array():
fp.write("ARRAY ")
fp.write(r.return_type())
fp.write(" );\n\n")
alist = at.keys()
alist.sort()
for an in alist:
r = defined_async_names[an]
if not r.recommended():
continue
fp.write("%%Async: %d\n" % r.request_nr())
fp.write(" %%Async-Name: %s\n" % r.request_name())
fp.write(" %%Async-Stable-Name: %s\n" % at[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover())
if r.recommended():
fp.write(" %Status: Recommended\n")
elif r.experimental():
fp.write(" %Status: Experimental\n")
elif r.obsolete():
fp.write(" %Status: Obsolete\n")
fp.write(" %%Obsoleted by: %s\n" % r.obsver())
else:
sys.stderr.write("No status found\n")
sys.exit(1)
fp.write("%End Async\n\n")
leader = "%s [%d]" % (r.request_name(), r.request_nr())
if len(r.arguments()) == 0:
fp.write("%s ( )" % (leader))
elif len(r.arguments()) == 1 and r.arguments()[0] != None:
argname, argtype, array = r.arguments()[0]
if array:
fp.write("%s ( %s : ARRAY %s )" % (leader,
argname, argtype))
else:
fp.write("%s ( %s : %s )" % (leader, argname, argtype))
else:
leader = "%s (( " % leader
fp.write(leader)
first = 1
for a in r.arguments():
if a == None:
continue
argname, argtype, array = a
if not first:
fp.write(";\n" + " " * len(leader))
if array:
fp.write("%-10s : ARRAY %s" % (argname, argtype))
else:
fp.write("%-10s : %s" % (argname, argtype))
first = 0
fp.write(" ))")
fp.write("\n\n")
fp.close()
os.rename(filename + ".tmp", filename)
if __name__ == '__main__':
l = lexer(sys.argv[1])
ret = l.run()
if ret == 0:
generate_stable_output()
generate_stable_output("protocol-a-full.txt", 0)
generate_stable_output("protocol-a-recommended.txt", 1)
generate_summary_output("protocol-a-current.txt")
elif ret == 1:
sys.exit(1)
else:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment