#!/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

[Powered by Free Software] [Graphics by Gimp] [Powered by GNU]
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("""
[XML | PYTHON]
"""); print_curved_footer(fp) write_pnetlib_footer(fp) fp.writeline("

AltStyle によって変換されたページ (->オリジナル) /

") 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("

"+""+cnode.fqname+"

") 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)