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: ...@@ -155,13 +155,14 @@ class prot_a_type:
""" """
self.__line = line self.__line = line
self.__protover = None self.__protover = None
self.__recommended = 0
def line_no(self): def line_no(self):
"""Return the line number that defined this type. """Return the line number that defined this type.
""" """
return self.__line return self.__line
def use(self, protover): def use(self, protover, recommended):
"""Mark this type as used by something else. """Mark this type as used by something else.
This will increase the usage count (returned by usage()) This will increase the usage count (returned by usage())
...@@ -171,12 +172,17 @@ class prot_a_type: ...@@ -171,12 +172,17 @@ class prot_a_type:
PROTOVER is the version of the request or async message that PROTOVER is the version of the request or async message that
uses this type. The type will remember the lowest PROTOVER; uses this type. The type will remember the lowest PROTOVER;
this is the protocol version where the type was introduced. 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 self.__usage_count = self.__usage_count + 1
if self.__protover == None or protover < self.__protover: if self.__protover == None or protover < self.__protover:
self.__protover = protover self.__protover = protover
if self.__usage_count == 1: if self.__usage_count == 1:
self.use_recurse(protover) self.use_recurse(protover, recommended)
if recommended:
self.__recommended = 1
def usage(self): def usage(self):
"""Return the usage count. """Return the usage count.
...@@ -188,10 +194,15 @@ class prot_a_type: ...@@ -188,10 +194,15 @@ class prot_a_type:
""" """
return self.__protover 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): class prot_a_builtin(prot_a_type):
"""Basic types defined by the protocol, such as INT32. """Basic types defined by the protocol, such as INT32.
""" """
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
pass pass
class prot_a_simple(prot_a_type): class prot_a_simple(prot_a_type):
...@@ -202,8 +213,8 @@ class prot_a_simple(prot_a_type): ...@@ -202,8 +213,8 @@ class prot_a_simple(prot_a_type):
self.__array = is_array self.__array = is_array
prot_a_type.__init__(self, line) prot_a_type.__init__(self, line)
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
defined_types[self.__type].use(protover) defined_types[self.__type].use(protover, recommended)
def base_type(self): def base_type(self):
return self.__type return self.__type
...@@ -220,9 +231,9 @@ class prot_a_alternate(prot_a_type): ...@@ -220,9 +231,9 @@ class prot_a_alternate(prot_a_type):
self.__type_b = type_b self.__type_b = type_b
prot_a_type.__init__(self, line) prot_a_type.__init__(self, line)
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
defined_types[self.__type_a].use(protover) defined_types[self.__type_a].use(protover, recommended)
defined_types[self.__type_b].use(protover) defined_types[self.__type_b].use(protover, recommended)
def type_a(self): def type_a(self):
return self.__type_a return self.__type_a
...@@ -252,9 +263,9 @@ class prot_a_struct(prot_a_type): ...@@ -252,9 +263,9 @@ class prot_a_struct(prot_a_type):
del undefined_fields[field_name] del undefined_fields[field_name]
return None return None
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
for (fn, tn, ar) in self.__fields: for (fn, tn, ar) in self.__fields:
defined_types[tn].use(protover) defined_types[tn].use(protover, recommended)
def fields(self): def fields(self):
return self.__fields return self.__fields
...@@ -289,7 +300,7 @@ class prot_a_bitstring(prot_a_type): ...@@ -289,7 +300,7 @@ class prot_a_bitstring(prot_a_type):
res.append("%s: bit ``%s'' not implemented" % (name, f)) res.append("%s: bit ``%s'' not implemented" % (name, f))
return res return res
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
pass pass
def bits(self): def bits(self):
...@@ -329,9 +340,9 @@ class prot_a_selection(prot_a_type): ...@@ -329,9 +340,9 @@ class prot_a_selection(prot_a_type):
def all_names(self): def all_names(self):
return self.__used_names.keys() 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: 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): def fields(self):
return self.__fields return self.__fields
...@@ -343,8 +354,8 @@ class prot_a_enumeration_of(prot_a_type): ...@@ -343,8 +354,8 @@ class prot_a_enumeration_of(prot_a_type):
prot_a_type.__init__(self, line) prot_a_type.__init__(self, line)
self.__base = base self.__base = base
def use_recurse(self, protover): def use_recurse(self, protover, recommended):
defined_types[self.__base].use(protover) defined_types[self.__base].use(protover, recommended)
def base_type(self): def base_type(self):
return self.__base return self.__base
...@@ -989,7 +1000,6 @@ class lexer: ...@@ -989,7 +1000,6 @@ class lexer:
self.error(line_no, "...clashing") self.error(line_no, "...clashing")
def __parse_async(self, req): def __parse_async(self, req):
protover = req.protover()
self.__tokens = [] self.__tokens = []
async = self.__get_token() async = self.__get_token()
if async != self.__amindex: if async != self.__amindex:
...@@ -1027,17 +1037,17 @@ class lexer: ...@@ -1027,17 +1037,17 @@ class lexer:
next = self.__get_token() next = self.__get_token()
if next != ')': if next != ')':
self.__unget_token(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() next = self.__get_token()
if next != ')': if next != ')':
self.error(self.__reader.line_no(), self.error(self.__reader.line_no(),
"missing close parenthesis after arguments") "missing close parenthesis after arguments")
return return
elif paren == '((': elif paren == '((':
req.append_arg(self.__parse_request_arg(protover)) req.append_arg(self.__parse_request_arg(req))
next = self.__get_token() next = self.__get_token()
while next == ';': while next == ';':
req.append_arg(self.__parse_request_arg(protover)) req.append_arg(self.__parse_request_arg(req))
next = self.__get_token() next = self.__get_token()
if next != '))': if next != '))':
self.error(self.__reader.line_no(), self.error(self.__reader.line_no(),
...@@ -1379,7 +1389,6 @@ class lexer: ...@@ -1379,7 +1389,6 @@ class lexer:
return prot_a_enumeration_of(line, name) return prot_a_enumeration_of(line, name)
def __parse_request(self, req_obj): def __parse_request(self, req_obj):
protover = req_obj.protover()
self.__tokens = [] self.__tokens = []
req = self.__get_token() req = self.__get_token()
if req != self.__findex: if req != self.__findex:
...@@ -1417,17 +1426,17 @@ class lexer: ...@@ -1417,17 +1426,17 @@ class lexer:
next = self.__get_token() next = self.__get_token()
if next != ')': if next != ')':
self.__unget_token(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() next = self.__get_token()
if next != ')': if next != ')':
self.error(self.__reader.line_no(), self.error(self.__reader.line_no(),
"missing close parenthesis after arguments") "missing close parenthesis after arguments")
return return
elif paren == '((': 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() next = self.__get_token()
while next == ';': 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() next = self.__get_token()
if next != '))': if next != '))':
self.error(self.__reader.line_no(), self.error(self.__reader.line_no(),
...@@ -1449,7 +1458,7 @@ class lexer: ...@@ -1449,7 +1458,7 @@ class lexer:
next = self.__get_token() next = self.__get_token()
if next != ')': if next != ')':
self.__unget_token(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) req_obj.set_return_type(ret_type, ret_array)
next = self.__get_token() next = self.__get_token()
if next != ')': if next != ')':
...@@ -1466,7 +1475,7 @@ class lexer: ...@@ -1466,7 +1475,7 @@ class lexer:
return return
def __parse_type(self, protover): def __parse_type(self, req_obj):
token = self.__get_lt_token() token = self.__get_lt_token()
if token == 'ARRAY': if token == 'ARRAY':
token = self.__get_lt_token() token = self.__get_lt_token()
...@@ -1478,7 +1487,7 @@ class lexer: ...@@ -1478,7 +1487,7 @@ class lexer:
if not defined_types.has_key(token): if not defined_types.has_key(token):
self.error(self.__reader.line_no(), self.error(self.__reader.line_no(),
"undefined type ``%s''" % token) "undefined type ``%s''" % token)
defined_types[token].use(protover) defined_types[token].use(req_obj.protover(), req_obj.recommended())
return (token, array) return (token, array)
def __get_lt_token(self): def __get_lt_token(self):
...@@ -1562,14 +1571,14 @@ class lexer: ...@@ -1562,14 +1571,14 @@ class lexer:
"bad argument ``%s''" % (arg,)) "bad argument ``%s''" % (arg,))
return not ok return not ok
def __parse_request_arg(self, protover): def __parse_request_arg(self, req_obj):
argname = self.__get_token() argname = self.__get_token()
if self.__bad_arg(argname): if self.__bad_arg(argname):
return return
if self.__get_token() != ':': if self.__get_token() != ':':
self.error(self.__reader.line_no(), "missing ``:'' after argument") self.error(self.__reader.line_no(), "missing ``:'' after argument")
return return
(tp, array) = self.__parse_type(protover) (tp, array) = self.__parse_type(req_obj)
if tp == None: if tp == None:
return return
if self.__args.has_key(argname): if self.__args.has_key(argname):
...@@ -1773,8 +1782,8 @@ class lexer: ...@@ -1773,8 +1782,8 @@ class lexer:
at[async_name] = stable at[async_name] = stable
ar[stable] = async_name ar[stable] = async_name
def generate_stable_output(): def generate_stable_output(filename, only_recommended):
fp = open("protocol-a.txt.tmp", "w") fp = open(filename + ".tmp", "w")
fp.write("# This protocol-a.txt, generated from Protocol-A.texi\n") 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("# by checkargs.py. This file contains the definitions\n")
fp.write("# of the types, requests and asynchronous messages in a\n") fp.write("# of the types, requests and asynchronous messages in a\n")
...@@ -1789,9 +1798,12 @@ def generate_stable_output(): ...@@ -1789,9 +1798,12 @@ def generate_stable_output():
fp.write("# stabilized a future version of the file will probably\n") fp.write("# stabilized a future version of the file will probably\n")
fp.write("# be placed in the public domain.\n") fp.write("# be placed in the public domain.\n")
fp.write("\n") fp.write("\n")
fp.write("# Note: this file does not describe request 12,\n") if only_recommended:
fp.write("# lookup-name, which returns Conf-List-Archaic.\n") fp.write("# This file only contains the recommended stuff.\n")
fp.write("# That is because that data type is so irregular.\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")
fp.write("\n") fp.write("\n")
fp.write("# Part 1: Define the alias names that Protocol-A.texi\n") fp.write("# Part 1: Define the alias names that Protocol-A.texi\n")
fp.write("# uses. These aliases will change from time to time, as\n") fp.write("# uses. These aliases will change from time to time, as\n")
...@@ -1810,6 +1822,8 @@ def generate_stable_output(): ...@@ -1810,6 +1822,8 @@ def generate_stable_output():
tlist.sort() tlist.sort()
for tn in tlist: 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"]: if tn != tt[tn] and tn not in ["Conf-List-Archaic"]:
fp.write("%%type-alias %-30s %s\n" % (tt[tn], tn)) fp.write("%%type-alias %-30s %s\n" % (tt[tn], tn))
...@@ -1820,6 +1834,9 @@ def generate_stable_output(): ...@@ -1820,6 +1834,9 @@ def generate_stable_output():
rlist.sort() rlist.sort()
for rn in rlist: 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"]: if rn != rt[rn] and rn not in ["lookup-name-1"]:
fp.write("%%request-alias %-30s %s\n" % (rt[rn], rn)) fp.write("%%request-alias %-30s %s\n" % (rt[rn], rn))
...@@ -1830,6 +1847,9 @@ def generate_stable_output(): ...@@ -1830,6 +1847,9 @@ def generate_stable_output():
alist.sort() alist.sort()
for an in alist: for an in alist:
if (only_recommended
and not defined_async_names[an].recommended()):
continue
if an != at[an]: if an != at[an]:
fp.write("%%async-alias %-30s %s\n" % (at[an], an)) fp.write("%%async-alias %-30s %s\n" % (at[an], an))
...@@ -1844,6 +1864,8 @@ def generate_stable_output(): ...@@ -1844,6 +1864,8 @@ def generate_stable_output():
if tn in ["Conf-List-Archaic-1"]: if tn in ["Conf-List-Archaic-1"]:
continue continue
t = defined_types[tr[tn]] t = defined_types[tr[tn]]
if only_recommended and not t.recommended():
continue
if isinstance(t, prot_a_builtin): if isinstance(t, prot_a_builtin):
fp.write("%%builtin %s\n" % tn) fp.write("%%builtin %s\n" % tn)
elif isinstance(t, prot_a_simple): elif isinstance(t, prot_a_simple):
...@@ -1914,6 +1936,8 @@ def generate_stable_output(): ...@@ -1914,6 +1936,8 @@ def generate_stable_output():
if rn in ["lookup-name-1"]: if rn in ["lookup-name-1"]:
continue continue
r = defined_request_names[rr[rn]] r = defined_request_names[rr[rn]]
if only_recommended and not r.recommended():
continue
fp.write("%%Request: %d\n" % r.request_nr()) fp.write("%%Request: %d\n" % r.request_nr())
fp.write(" %%Name: %s\n" % rt[r.request_name()]) fp.write(" %%Name: %s\n" % rt[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover()) fp.write(" %%Protocol version: %s\n" % r.protover())
...@@ -1970,6 +1994,8 @@ def generate_stable_output(): ...@@ -1970,6 +1994,8 @@ def generate_stable_output():
for an in alist: for an in alist:
r = defined_async_names[ar[an]] 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: %d\n" % r.request_nr())
fp.write(" %%Async-Name: %s\n" % at[r.request_name()]) fp.write(" %%Async-Name: %s\n" % at[r.request_name()])
fp.write(" %%Protocol version: %s\n" % r.protover()) fp.write(" %%Protocol version: %s\n" % r.protover())
...@@ -2013,13 +2039,209 @@ def generate_stable_output(): ...@@ -2013,13 +2039,209 @@ def generate_stable_output():
fp.write("\n\n") fp.write("\n\n")
fp.close() 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: