#!/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
""")
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(""" | [XML | PYTHON] | |
""");
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("")
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)