#!/usr/bin/python
##############################################
# This is released under the GNU GPL license #
# Copyright (c) FSF India #
# Author Gopal.V #
##############################################
import xml.dom.minidom
import string
import sys
from cvstree import *
cvs_entries=cvsmoddate("/opt/cvs/dotgnu/pnetlib/runtime")
cvs_sys_entries=cvsmoddate("/opt/cvs/dotgnu/pnetlib/")
#################TODO#####################
# #
# * implement error messages #
# * implement classes for html #
# * implement xml validation #
# * implement command line options #
# * implement theme/template support #
# * implement maintainer ids #
# * implement this whole thing in C# #
##########################################
class classnode:
def __init__(self,node):
self.node=node
self.name=node.getAttribute("name")
self.ns=node.getAttribute("namespace")
self.fqname=self.ns+"."+self.name
self.methods=node.getElementsByTagName("method")
self.fields=node.getElementsByTagName("field")
self.ctors=node.getElementsByTagName("ctor")
self.events=node.getElementsByTagName("event")
self.props=node.getElementsByTagName("property")
print "reading...."+self.fqname
def __repr__(self):
return ""
class filewrapper:
def __init__(self,fname,mode):
self.fp=open(fname,mode)
def write(self,data):
self.fp.write(data)
def writeline(self,data):
self.fp.write(data+"\n")
def writespecial(self,url): # escaped
hex=['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
for each in url:
val=ord(each)
if ((val>= ord('a') and val <= ord('z')) or (val>= ord('A') and val <= ord('Z'))): self.fp.write(each) elif each=='.': self.fp.write(each) else: self.fp.write("%%%c%c" % (hex[val /16],hex[val % 16])) def close(self): self.fp.close() #########################helper functions######################### # I had to write these because the minidom is not flexible enough# # well that's why it's called `mini' dom # # These could be improved upon, but I'm too lazy # ################################################################## def hasChildNode(parent,name): for node in parent.childNodes: if node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE: if(name=="*" or node.tagName == name): return node return 0 def get_prev_next(list,element): i=list.index(element) maxi=len(list)-1 # if(i==0): prev="index.html" else: prev=list[i-1]+".html" if(i==maxi): next="index.html" else: next=list[i+1]+".html" return (prev,next) def get_last_active(name): fname=name if(name[0:10]=="System.Xml"): fname=name[0:10]+string.replace(name[10:],".","/") else: fname=string.replace(name,".","/") try: retval=" last modified on "+cvs_entries.getDateStr(fname+".cs")+" "
return retval;
except KeyError:
try:
retval=" last modified on "+cvs_sys_entries.getDateStr(fname+".cs")+" "
return retval;
except KeyError:
return ""
#########################end helper functions####################
#status functions
def get_status(node,prefix=""):
child_error=len(node.getElementsByTagName("missing"))+\
len(node.getElementsByTagName("todo"))+\
len(node.getElementsByTagName("msg"))+\
len(node.getElementsByTagName("extra"))
if(hasChildNode(node,"todo")):
return (1,""+prefix+"TODO ")
if(hasChildNode(node,"missing")):
return (2,""+prefix+"Missing")
if (hasChildNode(node,"msg")):
msg=hasChildNode(node,"msg")
msg.normalize()
return (3,""+prefix+msg.childNodes[0].data+" ")
if(hasChildNode(node,"extra")):
return (4,""+prefix+"Extra ")
if(hasChildNode(node,"attribute")):
errnode=hasChildNode(node,"attribute")
return get_status(errnode,errnode.getAttribute("name")+" is ")
if(child_error!=0):
return (0,"")
return (0,"csdocvalil goofed up")
def split_signature(sig):
name=string.split(sig,"(")[0]
prefix=string.join(string.split(name)[0:-1]," ")
name=string.split(name)[-1]
params=string.split(sig,"(")[-1]
#remember ignore prefix for ctors
return (prefix,name,params)
#format functions
####MOST OF THIS STUFF HAS BEEN REVERSE ENGINEERED FROM PHPHNUKE's HTML####
##########################SO ALL CREDIT TO THEM############################
def print_curved_header(fp,header=""):
fp.writeline("""""")
fp.writeline(""" """)
fp.writeline(" "+header+"")
fp.writeline("
")
fp.writeline("")
def print_curved_footer(fp):
fp.writeline(" ")
fp.writeline(" ")
fp.writeline("
")
fp.writeline("")
fp.writeline("")
def print_curved_title(fp,title=""):
fp.writeline(" ")
fp.writeline(" "+title+"")
fp.writeline("
")
def write_pnetlib_header(fp):
#print_curved_header(fp,"""Pnetlib Class Status """)
##ADDED A COOL LOGO,
print_curved_header(fp,"""""")
print_curved_title(fp,"""Portable.NET""")
def write_pnetlib_footer(fp):
fp.writeline(" ")
import time
lastd=time.gmtime(time.time());
print_curved_header(fp," ")
print_curved_title(fp,"""
This document is licensed under the GNU FDL.
"""+"Last Updated on "+`lastd[2]`+"-"+`lastd[1]`+"-"+`lastd[0]`+" "
+"""
Visit
http://www.dotgnu.org for more details
Maintained by Gopal.V
""")
print_curved_footer(fp)
#end format functions
def print_namespace_list(nslist,ctor,method,field,prop,event):
#nslist=nsdict.keys()
#nslist.sort()
fp=filewrapper("index.html","w")
fp.writeline("""""")
fp.writeline("""
Portable.Net Status Page """)
write_pnetlib_header(fp)
print_curved_title(fp,"""
Namespaces """)
print_curved_title(fp,"
\
")
fp.writeline("
")
#nested tabling is *so* difficult
fp.writeline("""""")
fp.writeline("
")
fp.writeline("")
fp.writeline(""" """)
fp.writeline("""
Namespaces
""")
fp.writeline("""
""")
for each in nslist:
fp.writeline(" ·
"+each+" ")
fp.writeline("""
""")
fp.writeline("""
""")
fp.writeline("""
""")
fp.writeline(""" """)
fp.writeline("")
fp.writeline(""" """)
fp.writeline(""" """)
fp.writeline("""
""")
fp.writeline("
In the "+`len(nslist)`+" namespaces
")
fp.writeline("
we are missing:
")
fp.writeline("
"+`ctor`+" constructors, ")
fp.writeline("
"+`method`+" methods, ")
fp.writeline("
"+`field`+" fields, ")
fp.writeline("
"+`prop`+" properties, and ")
fp.writeline("
"+`event`+" events. ")
fp.writeline("""
""")
fp.writeline(""" """)
fp.writeline("
")
fp.writeline("")
fp.writeline("
")
fp.writeline("""
""");
print_curved_footer(fp)
write_pnetlib_footer(fp)
fp.writeline("
")
fp.close()
#Namespace functions....
##########################SUMMARY FUNCTIONS#################################
def print_method_summary(fp,parent,methods):
fp.writeline(" ")
fp.writeline("""""")
fp.writeline("""
Method Summary
""")
fp.writeline("")
fp.writeline("""""")
method_count_dict={}
for each in methods:
sig=each.getAttribute("signature")
(prefix,name,params)=split_signature(sig)
if(method_count_dict.has_key(name)):
method_count_dict[name]=method_count_dict[name]+1
else:
method_count_dict[name]=1
for each in methods:
(status,msg)=get_status(each)
sig=each.getAttribute("signature")
(prefix,name,params)=split_signature(sig)
fp.writeline("
"+prefix+" ")
#write doc filename
#due to rhys simpilifying documentation, I'm forced to
#complicate my program, to make it simpler to access
fp.write(""+name+" ")
fp.writeline(" ("+params+" "+msg+"
")
fp.writeline("")
fp.writeline("
")
##clone the above code for all the summaries
def print_field_summary(fp,parent,fields):
fp.writeline(" ")
fp.writeline("""""")
fp.writeline("""
Field Summary
""")
fp.writeline("")
fp.writeline("""""")
for each in fields:
(status,msg)=get_status(each)
name=each.getAttribute("name")
type=each.getAttribute("type")
fp.writeline("
"+type+" ")
#write doc filename
#due to rhys simpilifying documentation, I'm forced to
#complicate my program, to make it simpler to access
fp.writeline("")
fp.writeline(name);
fp.writeline(" ");
fp.writeline(" "+msg+"
")
fp.writeline("")
fp.writeline("
")
def print_ctor_summary(fp,parent,ctors):
fp.writeline(" ")
fp.writeline("""""")
fp.writeline("""
Constructor Summary
""")
fp.writeline("")
fp.writeline("""""")
ctor_count_dict={}
for each in ctors:
sig=each.getAttribute("signature")
(prefix,name,params)=split_signature(sig)
if(ctor_count_dict.has_key(name)):
ctor_count_dict[name]=ctor_count_dict[name]+1
else:
ctor_count_dict[name]=1
for each in ctors:
(status,msg)=get_status(each)
sig=each.getAttribute("signature")
(prefix,name,params)=split_signature(sig)
fp.writeline("
")
#write doc filename
#due to rhys simpilifying documentation, I'm forced to
#complicate my program, to make it simpler to access
fp.write(""+name+" ")
fp.writeline(" ("+params+" "+msg+"
")
fp.writeline("")
fp.writeline("
")
def print_prop_summary(fp,parent,props):
fp.writeline(" ")
fp.writeline("""""")
fp.writeline("""
Property Summary
""")
fp.writeline("")
fp.writeline("""""")
for each in props:
(status,msg)=get_status(each)
name=each.getAttribute("name")
type=each.getAttribute("type")
fp.writeline("
"+type+" ");
#write doc filename
#due to rhys simpilifying documentation, I'm forced to
#complicate my program, to make it simpler to access
fp.writeline("")
fp.writeline(name);
fp.writeline(" ");
fp.writeline(" "+msg+"
")
fp.writeline("")
fp.writeline("
")
def print_event_summary(fp,events):
fp.writeline(" ")
fp.writeline("""""")
fp.writeline("""
Event Summary
""")
fp.writeline("")
fp.writeline("""""")
for each in events:
(status,msg)=get_status(each)
name=each.getAttribute("name")
fp.writeline("
"+name+" "+msg+"
")
fp.writeline("")
fp.writeline("
")
###################################END SUMMARY##############################
def print_each_class(fp,cnode):
# fp.writeline(" ")
fp.writeline("")
fp.writeline("")
fp.writeline("")
(status,msg)=get_status(cnode.node)
fp.writeline(""" Status : """)
fp.writeline(msg)
last_active=get_last_active(cnode.fqname)
fp.writeline(last_active)
fp.writeline("
")
#summary
if(len(cnode.ctors)!=0):
print_ctor_summary(fp,cnode,cnode.ctors)
if(len(cnode.methods)!=0):
print_method_summary(fp,cnode,cnode.methods)
if(len(cnode.fields)!=0):
print_field_summary(fp,cnode,cnode.fields)
if(len(cnode.props)!=0):
print_prop_summary(fp,cnode,cnode.props)
if(len(cnode.events)!=0):
print_event_summary(fp,cnode.events)
fp.writeline("")
fp.writeline(" ")
fp.writeline(" ")
def print_namespace_inner(fname,classlist,prev,next):
fp=filewrapper(fname+".html","w")
print "writing....."+fname+".html"
fp.writeline("""""")
fp.writeline("""%s
"""%(fname))
write_pnetlib_header(fp)
print_curved_title(fp,""+fname+" Namespace ")
links=""
if(prev!="index.html"):
links=links+"\ "
links=links+"\ "
if(next!="index.html"):
links=links+"\>\"src=\"rarrow.jpg\" border=\"0\"> "
links=links+"
"
print_curved_title(fp,links)
fp.writeline(" ")
fp.writeline("")
fp.writeline("""""")
fp.writeline("""
""")
fp.writeline("")
fp.writeline(""" """)
fp.writeline("""
Classes
""")
fp.writeline("""
""")
methodcount=0
ctorcount=0
eventcount=0
fieldcount=0
propcount=0
for each in classlist:
fp.writeline(" ·
"+each.name+" ")
ctorcount=ctorcount+len(each.ctors)
methodcount=methodcount+len(each.methods)
fieldcount=fieldcount+len(each.fields)
eventcount=eventcount+len(each.events)
propcount=propcount+len(each.props)
fp.writeline("""
""")
fp.writeline(""" """)
fp.writeline(""" """)
fp.writeline("")
fp.writeline("
")
fp.writeline("
There are "+`len(classlist)`+" incomplete classes in this namespace
")
fp.writeline("
In total we are missing :
")
fp.writeline("
"+`ctorcount`+" constructors, ")
fp.writeline("
"+`methodcount`+" methods, ")
fp.writeline("
"+`fieldcount`+" fields, ")
fp.writeline("
"+`propcount`+" properties, and ")
fp.writeline("
"+`eventcount`+" events.")
fp.writeline("
")
fp.writeline("""
""")
fp.writeline(""" """)
fp.writeline("
")
#classwise printing starts
for each in classlist:
fp.writeline("""
""")
fp.writeline(""" """)
print_each_class(fp,each)
fp.writeline("
")
print_curved_footer(fp)
write_pnetlib_footer(fp)
fp.writeline("")
fp.close()
return (ctorcount,methodcount,fieldcount,propcount,eventcount)
if __name__=="__main__":
root=xml.dom.minidom.parse('status.xml')
classes=root.getElementsByTagName("class")
classnodes=[]
nsdict={}
for each in classes:
c=classnode(each);
classnodes.append(c)
if (nsdict.has_key(c.ns)):
a=nsdict.get(c.ns)
else:
a=[]
a.append(c)
nsdict.update({c.ns:a})
ctorcount=0
methodcount=0
propcount=0
eventcount=0
fieldcount=0
nslist=nsdict.keys()
nslist.sort()
for each in nslist:
#print nsdict.get(each)
(prev,next)=get_prev_next(nslist,each)
(ctor,method,field,prop,event)=print_namespace_inner(each,nsdict.get(each),prev,next)
ctorcount=ctorcount+ctor
propcount=propcount+prop
fieldcount=fieldcount+field
eventcount=eventcount+event
methodcount=methodcount+method
print_namespace_list(nslist,ctorcount,methodcount,fieldcount,propcount,eventcount)