#!/usr/bin/python
import lutinDebug as debug
import sys
import lutinTools
import CppHeaderParser
import re
import codeBB
import collections
global_class_link = {
"std::string" : "http://www.cplusplus.com/reference/string/string/",
"std::u16string" : "http://www.cplusplus.com/reference/string/u16string/",
"std::u32string" : "http://www.cplusplus.com/reference/string/u32string/",
"std::wstring" : "http://www.cplusplus.com/reference/string/wstring/",
"std::vector" : "http://www.cplusplus.com/reference/vector/vector/"
}
def replace_type(match):
value = "" + match.group() + ""
return value
def replace_storage_keyword(match):
value = "" + match.group() + ""
return value
def display_color(valBase):
# storage keyword :
p = re.compile("(inline|const|class|virtual|private|public|protected|friend|const|extern|auto|register|static|volatile|typedef|struct|union|enum)")
val = p.sub(replace_storage_keyword, valBase)
# type :
p = re.compile("(bool|BOOL|char(16_t|32_t)?|double|float|u?int(8|16|32|64|128)?(_t)?|long|short|signed|size_t|unsigned|void|(I|U)(8|16|32|64|128))")
val = p.sub(replace_type, val)
return val, len(valBase)
def display_type(type, myDoc):
type = type.replace("inline ", "")
lenght = 0;
isFirst = True
out = ''
# we split all the element in list sepa=rated with space to keep class... and standard c+ class
for element in type.split(' '):
if isFirst == False:
out += " "
lenght += 1
isFirst = False
# check if the element in internal at the current lib
name, link = myDoc.get_class_link(element)
if len(link) != 0:
out += "" + name + ""
lenght += len(element)
# Ckeck if the variable in a standard class:
elif element in global_class_link.keys():
out += "" + element + ""
lenght += len(element)
else:
data, lenghtTmp = display_color(element)
out += data
lenght += lenghtTmp
# get every subelement class :
return [out,lenght]
def display_doxygen_param(comment, input, output):
data = "Parameter"
if input == True:
data += " [input]"
if output == True:
data += " [output]"
data += ": "
#extract first element:
val = comment.find(" ")
var = comment[:val]
endComment = comment[val:]
# TODO : Check if it exist in the parameter list ...
data += "" + var + " " + endComment
data += " "
return data
def parse_doxygen(data) :
pos = data.find("/*");
if pos > 0:
data = data[pos:]
if data[0] == '/' \
and data[1] == '*' \
and data[2] == '*':
data = data[3:len(data)-2]
data = data.replace("\n** ", "\n")
data = data.replace("\n**", "\n")
data = data.replace("\n* ", "\n")
data = data.replace("\n*", "\n")
data = data.replace("\n ** ", "\n")
data = data.replace("\n **", "\n")
data = data.replace("\n * ", "\n")
data = data.replace("\n *", "\n")
data = data.replace("\r", '')
streams = data.split("@")
data2 = ''
for element in streams:
if element[:1] == "\n" \
or element[:2] == "\n\n":
# nothing to do : Nomale case of the first \n
None
elif element[:6] == "brief ":
data2 += element[6:]
data2 += " "
for element in streams:
if element[:1] == "\n" \
or element[:2] == "\n\n":
# nothing to do : Nomale case of the first \n
None
elif element[:5] == "note ":
data2 += "Notes: "
data2 += element[5:]
data2 += " "
data3 = ''
for element in streams:
if element[:1] == "\n" \
or element[:2] == "\n\n":
# nothing to do : Nomale case of the first \n
None
elif element[:14] == "param[in,out] " \
or element[:14] == "param[out,in] ":
data3 += display_doxygen_param(element[14:], True, True)
elif element[:10] == "param[in] ":
data3 += display_doxygen_param(element[10:], True, False)
elif element[:11] == "param[out] ":
data3 += display_doxygen_param(element[11:], False, True)
elif element[:6] == "param ":
data3 += display_doxygen_param(element[6:], False, False)
elif element[:7] == "return ":
data3 += "Return: "
data3 += element[7:]
data3 += " "
if data3 != '':
data2 += "
\n'
globalList = []
for className in myDoc.listClass.keys() :
element = myDoc.listClass[className]
if "doxygen" in element.keys():
if element["doxygen"].find("@not-in-doc") >= 0:
continue
globalList.append(className)
for enumName in myDoc.listEnum.keys() :
element = myDoc.listEnum[enumName]
if "doxygen" in element.keys():
if element["doxygen"].find("@not-in-doc") >= 0:
continue
globalList.append(enumName)
# check if all element start wuth the lib namespace (better for interpretations ...)
allSartWithModuleName = True
for className in sorted(globalList) :
if className[:len(myDoc.moduleName)+2] != myDoc.moduleName+"::":
allSartWithModuleName = False
break
# create the class tree ...
myTree = createTree(globalList)
genericHeader += '
\n'
if len(myTree.keys()) == 1 \
and myDoc.moduleName in myTree.keys():
myTree = myTree[myDoc.moduleName]
# todo : in this case I will create a lib element and set all global element in it, other namespace will have there own entry ...:
# ewol
# ewol
# widget
# compositing
# resources
# sys
for element in sorted(myTree.keys()) :
logicalNamespace = element[0].lower() + element[1:]
logicalClass = element[0].upper() + element[1:]
# reject class that have the same name of a namespace ==> set it in the namespace ...
if logicalNamespace != element: # this is a class :
if element in myTree.keys():
continue
#get elemement
subElementTree = myTree[element]
if len(myTree.keys()) != 1:
# TODO : ...
None
if len(subElementTree.keys()) == 0:
genericHeader += '
\n'
# check if we checking a namespace with a classe name is availlable ...
if logicalNamespace == element:
if logicalClass in myTree.keys():
genericHeader += '
");
file.write(" ");
file.write("TODO : Main page ...");
file.write(" ");
file.write(" ");
file.write(genericFooter)
file.close();
for className in sorted(myDoc.listClass.iterkeys()) :
localClass = myDoc.listClass[className]
debug.debug(" class: " + className)
classFileName = outFolder + "/" + class_name_to_file_name(className)
# create directory (in case)
lutinTools.CreateDirectoryOfFile(classFileName);
debug.printElement("doc", myDoc.moduleName, "<==", className)
# open the file :
file = open(classFileName, "w")
file.write(genericHeader)
file.write("
Class: " + className + "
\n")
file.write(" \n")
# calculate function max size return & function name size:
sizeReturn=0
sizefunction=0
for function in localClass["methods"]["public"]:
sizefunction = calsulateSizeFunction(function, sizefunction)
sizeReturn = calsulateSizeReturn(function, sizeReturn)
for function in localClass["methods"]["protected"]:
sizefunction = calsulateSizeFunction(function, sizefunction)
sizeReturn = calsulateSizeReturn(function, sizeReturn)
for function in localClass["methods"]["private"]:
sizefunction = calsulateSizeFunction(function, sizefunction)
sizeReturn = calsulateSizeReturn(function, sizeReturn)
file.write("
Constructor and Destructor:
\n")
file.write("
\n");
for function in localClass["methods"]["public"]:
if function['destructor'] \
or function['constructor'] :
display_reduct_function(function, file, "+ ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["protected"]:
if function['destructor'] \
or function['constructor'] :
display_reduct_function(function, file, "# ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["private"]:
if function['destructor'] \
or function['constructor'] :
display_reduct_function(function, file, "- ", sizeReturn, sizefunction, myDoc)
file.write("
\n");
file.write("
Synopsis:
\n")
# display all functions :
# TODO: ...
file.write("
\n");
for function in localClass["methods"]["public"]:
if not function['destructor'] \
and not function['constructor'] :
display_reduct_function(function, file, "+ ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["protected"]:
if not function['destructor'] \
and not function['constructor'] :
display_reduct_function(function, file, "# ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["private"]:
if not function['destructor'] \
and not function['constructor'] :
display_reduct_function(function, file, "- ", sizeReturn, sizefunction, myDoc)
file.write("
\n");
file.write("\n")
file.write("\n")
heritage = myDoc.get_heritage_list(className)
heritageDown = myDoc.get_down_heritage_list(className)
if len(heritage) > 1 \
or len(heritageDown) > 0:
file.write("
Object Hierarchy:
\n")
file.write("
\n")
level = 0;
for heritedClass in heritage:
if level != 0:
file.write(white_space(level*4) + "+--> ")
if heritedClass != className:
name, link = myDoc.get_class_link(heritedClass)
file.write("" + name + "\n")
else:
file.write("" + heritedClass + "\n")
level += 1;
for heritedClass in heritageDown:
file.write(white_space(level*4) + "+--> ")
name, link = myDoc.get_class_link(heritedClass)
file.write("" + name + "\n")
file.write("
\n")
file.write(" \n")
"""
file.write("
Signals:
\n")
# display all signals :
# TODO: ...
file.write("
Configuration:
\n")
# display all configuration :
# TODO: ...
"""
if "doxygen" in localClass:
file.write("
Description:
\n")
# display Class description :
file.write(localClass["doxygen"])
file.write("
Detail:
\n")
# display all the class internal functions :
for function in localClass["methods"]["public"]:
displayFunction(localClass['namespace'] , function, file, "+ ", sizeReturn, sizefunction, myDoc)
file.write("\n\n")
for function in localClass["methods"]["protected"]:
displayFunction(localClass['namespace'] , function, file, "# ", sizeReturn, sizefunction, myDoc)
file.write("\n\n")
for function in localClass["methods"]["private"]:
displayFunction(localClass['namespace'] , function, file, "- ", sizeReturn, sizefunction, myDoc)
file.write("\n\n")
file.write(genericFooter)
file.close()
for enumName in sorted(myDoc.listEnum.iterkeys()) :
localEnum = myDoc.listEnum[enumName]
debug.debug(" enum: " + enumName)
fileName = outFolder + "/" + class_name_to_file_name(enumName)
# create directory (in case)
lutinTools.CreateDirectoryOfFile(fileName);
debug.printElement("doc", myDoc.moduleName, "<==", enumName)
# open the file :
file = open(fileName, "w")
file.write(genericHeader)
file.write("