diff --git a/lutin.py b/lutin.py
index 9579bf0..07954c3 100755
--- a/lutin.py
+++ b/lutin.py
@@ -41,9 +41,11 @@ def usage():
print " Clean all (same as previous)"
print " dump"
print " Dump all the module dependency and properties"
+ print " doc"
+ print " Create documentation of all module that is mark as availlable on it"
listOfAllModule = lutinModule.ListAllModuleWithDesc()
for mod in listOfAllModule:
- print " " + mod[0] + " / " + mod[0] + "-clean / " + mod[0] + "-dump"
+ print " " + mod[0] + " / " + mod[0] + "-clean / " + mod[0] + "-dump" + mod[0] + "-doc"
print " " + mod[1]
print " ex: " + sys.argv[0] + " all --target=Android all -t Windows -m debug all"
exit(0)
diff --git a/lutinDoc.py b/lutinDoc.py
index c5ee045..f727036 100644
--- a/lutinDoc.py
+++ b/lutinDoc.py
@@ -17,10 +17,11 @@ class doc:
def __init__(self, moduleName):
self.moduleName = moduleName
self.listClass = dict()
+ self.listEnum = dict()
self.listVariable = dict()
self.listFunction = dict()
self.listNamepsaces = dict()
-
+ self.target = None
##
## @brief Add a File at the parsing system
@@ -32,9 +33,11 @@ class doc:
try:
metaData = CppHeaderParser.CppHeader(filename)
except CppHeaderParser.CppParseError, e:
- debug.error(" can not parse the file: '" + filename + "' error : " + e)
+ debug.warning(" can not parse the file: '" + filename + "' error : " + str(e))
return False
+ #debug.info(str(metaData.enums))
+
# add all classes :
for element in metaData.classes:
localClass = metaData.classes[element]
@@ -47,6 +50,20 @@ class doc:
else:
self.listClass[className] = localClass
+ # add all enums:
+ for localEnum in metaData.enums:
+ if localEnum['namespace'] == '':
+ enumName = localEnum['name']
+ else:
+ enumName = localEnum['namespace'] + "::" + localEnum['name']
+ enumName = enumName.replace("::::", "::")
+ if enumName in self.listEnum.keys():
+ debug.warning("Might merge enum : '" + enumName + "' file : " + filename)
+ else:
+ self.listEnum[enumName] = localEnum
+
+ # add all namaspace:
+
# add all namespaces:
# add all global vars:
@@ -60,7 +77,9 @@ class doc:
## @param[in] destFolder Destination folder.
## @param[in] mode (optinnal) generation output mode {html, markdown ...}
##
- def generate_documantation(self, destFolder, mode="html"):
+ def generate_documantation(self, target, destFolder, mode="html"):
+ # local store of the target
+ self.target = target
if mode == "html":
if lutinDocHtml.generate(self, destFolder) == False:
debug.warning("Generation Documentation :'" + mode + "' ==> return an error for " + self.moduleName)
@@ -69,7 +88,9 @@ class doc:
None
else:
debug.error("Unknow Documantation mode generation :'" + mode + "'")
+ self.target = None
return False
+ self.target = None
return True
##
@@ -110,4 +131,66 @@ class doc:
break;
debug.verbose("find childs : " + str(list))
return list
+
+ ##
+ ## @brief trnsform the classname in a generic link (HTML)
+ ## @param[in] elementName Name of the class requested
+ ## @return [className, link]
+ ##
+ def get_class_link(self, elementName):
+ if elementName == "const" \
+ or elementName == "enum" \
+ or elementName == "void" \
+ or elementName == "char" \
+ or elementName == "char32_t" \
+ or elementName == "float" \
+ or elementName == "double" \
+ or elementName == "bool" \
+ or elementName == "int8_t" \
+ or elementName == "uint8_t" \
+ or elementName == "int16_t" \
+ or elementName == "uint16_t" \
+ or elementName == "int32_t" \
+ or elementName == "uint32_t" \
+ or elementName == "int64_t" \
+ or elementName == "uint64_t" \
+ or elementName == "int" \
+ or elementName == "T" \
+ or elementName == "CLASS_TYPE" \
+ or elementName[:5] == "std::" \
+ or elementName[:6] == "appl::" \
+ or elementName == "&" \
+ or elementName == "*" \
+ or elementName == "**":
+ return [elementName, ""]
+ if elementName in self.listClass.keys():
+ link = elementName.replace(":","_") + ".html"
+ return [elementName, link]
+ elif elementName in self.listEnum.keys():
+ link = elementName.replace(":","_") + ".html"
+ return [elementName, link]
+ else:
+ return self.target.doc_get_link(elementName)
+ return [elementName, ""]
+
+ ##
+ ## @brief trnsform the classname in a generic link (HTML) (external access ==> from target)
+ ## @param[in] elementName Name of the class requested
+ ## @return [className, link]
+ ##
+ def get_class_link_from_target(self, elementName):
+ # reject when auto call :
+ if self.target != None:
+ return [elementName, ""]
+ # search in local list :
+ if elementName in self.listClass.keys():
+ link = elementName.replace(":","_") + ".html"
+ return [elementName, "../" + self.moduleName + "/" + link]
+ elif elementName in self.listEnum.keys():
+ link = elementName.replace(":","_") + ".html"
+ return [elementName, "../" + self.moduleName + "/" + link]
+ # did not find :
+ return [elementName, ""]
+
+
diff --git a/lutinDocHtml.py b/lutinDocHtml.py
index 2aa6c7d..5b3b794 100644
--- a/lutinDocHtml.py
+++ b/lutinDocHtml.py
@@ -24,14 +24,14 @@ def replace_storage_keyword(match):
def display_color(valBase):
# storage keyword :
- p = re.compile("(inline|const|class|virtual|private|public|protected|friend|const|extern|auto|register|static|unsigned|signed|volatile|char|double|float|int|long|short|void|typedef|struct|union|enum)")
+ 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, localClassName):
+def display_type(type, myDoc):
type = type.replace("inline ", "")
lenght = 0;
isFirst = True
@@ -43,12 +43,10 @@ def display_type(type, localClassName):
lenght += 1
isFirst = False
# check if the element in internal at the current lib
- if element[:len(localClassName)] == localClassName:
- out += "" + element + ""
+ name, link = myDoc.get_class_link(element)
+ if len(link) != 0:
+ out += "" + name + ""
lenght += len(element)
- # check if the element is in local Lib:
- elif False:
- None
# Ckeck if the variable in a standard class:
elif element in global_class_link.keys():
out += "" + element + ""
@@ -148,7 +146,7 @@ def white_space(size) :
ret += " "
return ret
-def displayReductFunction(function, file, classement, sizeReturn, sizefunction, localClassName) :
+def display_reduct_function(function, file, classement, sizeReturn, sizefunction, myDoc) :
file.write(classement + " ")
lenght = len(classement)+1;
if function['destructor'] :
@@ -158,7 +156,7 @@ def displayReductFunction(function, file, classement, sizeReturn, sizefunction,
file.write(white_space(sizeReturn+1))
lenght += sizeReturn+1;
else :
- typeData, typeLen = display_type(function["rtnType"], localClassName);
+ typeData, typeLen = display_type(function["rtnType"], myDoc);
file.write(typeData)
file.write(white_space(sizeReturn+1 - typeLen))
lenght += sizeReturn+1;
@@ -172,7 +170,7 @@ def displayReductFunction(function, file, classement, sizeReturn, sizefunction,
file.write(",
")
file.write(white_space(parameterPos))
- typeData, typeLen = display_type(param["type"], localClassName);
+ typeData, typeLen = display_type(param["type"], myDoc);
file.write(typeData)
if param['name'] != "":
file.write(" ")
@@ -182,7 +180,7 @@ def displayReductFunction(function, file, classement, sizeReturn, sizefunction,
file.write("
")
-def displayFunction(namespace, function, file, classement, sizeReturn, sizefunction, localClassName) :
+def displayFunction(namespace, function, file, classement, sizeReturn, sizefunction, myDoc) :
lineData = ""
if ( function['constructor'] == True \
or function['destructor'] == True \
@@ -201,7 +199,7 @@ def displayFunction(namespace, function, file, classement, sizeReturn, sizefunct
elif function['constructor'] :
lenght = 0;
else :
- typeData, typeLen = display_type(function["rtnType"], localClassName);
+ typeData, typeLen = display_type(function["rtnType"], myDoc);
file.write(typeData + " ")
lenght = typeLen+1;
@@ -212,7 +210,7 @@ def displayFunction(namespace, function, file, classement, sizeReturn, sizefunct
if isFirst == False:
file.write(",\n")
file.write(white_space(parameterPos))
- typeData, typeLen = display_type(param["type"], localClassName);
+ typeData, typeLen = display_type(param["type"], myDoc);
file.write(typeData)
if param['name'] != "":
file.write(" ")
@@ -253,13 +251,13 @@ def generate(myDoc, outFolder) :
genericHeader += "\n"
genericHeader += "
\n"
genericHeader += " \n"
- genericHeader += " Ewol Library\n"
+ genericHeader += " " + myDoc.moduleName+ " Library\n"
genericHeader += " \n"
genericHeader += "\n"
genericHeader += "\n"
genericHeader += " \n"
genericHeader += "
\n"
- genericHeader += "
Ewol Library
\n"
+ genericHeader += "
" + myDoc.moduleName+ " Library
\n"
#genericHeader += "
\n"
baseNamespace = ""
for className in sorted(myDoc.listClass.iterkeys()) :
@@ -281,6 +279,27 @@ def generate(myDoc, outFolder) :
if baseNamespace != "":
genericHeader += "
\n"
+
+ for enumName in sorted(myDoc.listEnum.iterkeys()) :
+ pos = enumName.find("::")
+ if pos >= 0:
+ namespace = enumName[:pos]
+ rest = enumName[pos+2:]
+ else:
+ namespace = ""
+ rest = enumName
+ if baseNamespace != namespace:
+ if baseNamespace != "":
+ genericHeader += " \n"
+ genericHeader += "
" + namespace + "\n"
+ genericHeader += "
\n"
+ baseNamespace = namespace
+
+ genericHeader += " - " + rest + "
\n"
+
+ if baseNamespace != "":
+ genericHeader += "
\n"
+
#genericHeader += " \n"
genericHeader += "
\n"
genericHeader += "
\n"
@@ -303,9 +322,8 @@ def generate(myDoc, outFolder) :
file.write(genericHeader)
- file.write("" + className + "
\n")
- file.write("\n")
- file.write("\n")
+ file.write("Class: " + className + "
\n")
+ file.write("
\n")
# calculate function max size return & function name size:
sizeReturn=0
sizefunction=0
@@ -324,11 +342,11 @@ def generate(myDoc, outFolder) :
# TODO: ...
file.write("\n");
for function in localClass["methods"]["public"]:
- displayReductFunction(function, file, "+ ", sizeReturn, sizefunction, className)
+ display_reduct_function(function, file, "+ ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["protected"]:
- displayReductFunction(function, file, "# ", sizeReturn, sizefunction, className)
+ display_reduct_function(function, file, "# ", sizeReturn, sizefunction, myDoc)
for function in localClass["methods"]["private"]:
- displayReductFunction(function, file, "- ", sizeReturn, sizefunction, className)
+ display_reduct_function(function, file, "- ", sizeReturn, sizefunction, myDoc)
file.write("
\n");
file.write("\n")
file.write("\n")
@@ -343,13 +361,15 @@ def generate(myDoc, outFolder) :
if level != 0:
file.write(white_space(level*4) + "+--> ")
if heritedClass != className:
- file.write("" + heritedClass + "\n")
+ 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) + "+--> ")
- file.write("" + heritedClass + "\n")
+ name, link = myDoc.get_class_link(heritedClass)
+ file.write("" + name + "\n")
file.write("\n")
file.write("
\n")
"""
@@ -371,18 +391,47 @@ def generate(myDoc, outFolder) :
file.write("Detail:\n")
# display all the class internal functions :
for function in localClass["methods"]["public"]:
- displayFunction(localClass['namespace'] , function, file, "+ ", sizeReturn, sizefunction, className)
+ 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, className)
+ 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, className)
+ 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("Enum: " + enumName + "
\n")
+ file.write("
\n")
+ file.write("Value :
\n")
+ file.write("\n")
+ #debug.info(" enum: " + str(localEnum))
+ for value in localEnum["values"]:
+ file.write("- " + value["name"])
+ if "doxygen" in value.keys():
+ file.write(" " + value["doxygen"] )
+ file.write("
")
+ file.write("
\n")
+
+ file.write(genericFooter)
+
+ file.close()
+
diff --git a/lutinModule.py b/lutinModule.py
index 8b0e850..a139175 100644
--- a/lutinModule.py
+++ b/lutinModule.py
@@ -13,19 +13,17 @@ import lutinMultiprocess
import lutinEnv
import lutinDoc
-"""
-
-"""
class module:
- """
- Module class represent all system needed for a specific
- module like
- - type (bin/lib ...)
- - dependency
- - flags
- - files
- - ...
- """
+
+ ##
+ ## @brief Module class represent all system needed for a specific
+ ## module like
+ ## - type (bin/lib ...)
+ ## - dependency
+ ## - flags
+ ## - files
+ ## - ...
+ ##
def __init__(self, file, moduleName, moduleType):
## Remove all variable to prevent error of multiple deffinition of the module ...
self.originFile=''
@@ -37,8 +35,8 @@ class module:
# Dependency list:
self.depends=[]
# Dependency list:
- self.docPath=lutinTools.GetCurrentPath(file)
- self.documentation = lutinDoc.doc(self.name)
+ self.docPath = ""
+ self.documentation = None
# export PATH
self.export_path=[]
self.local_path=[]
@@ -94,9 +92,9 @@ class module:
}
- ###############################################################################
- ## add Some copilation flags for this module (and only this one)
- ###############################################################################
+ ##
+ ## @brief Add Some copilation flags for this module (and only this one)
+ ##
def add_extra_compile_flags(self):
self.CompileFlags_CC([
"-Wall",
@@ -106,9 +104,9 @@ class module:
"-Wno-write-strings"]);
#only for gcc : "-Wunused-variable", "-Wunused-but-set-variable",
- ###############################################################################
- ## remove all unneeded warning on compilation ==> for extern libs ...
- ###############################################################################
+ ##
+ ## @brief remove all unneeded warning on compilation ==> for extern libs ...
+ ##
def remove_compile_warning(self):
self.CompileFlags_CC([
"-Wno-int-to-pointer-cast"
@@ -118,9 +116,9 @@ class module:
])
# only for gcc :"-Wno-unused-but-set-variable"
- ###############################################################################
- ## Commands for running gcc to compile a m++ file.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to compile a m++ file.
+ ##
def Compile_mm_to_o(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.fileGenerateObject(binary,self.name,self.originFolder,file)
# create the command line befor requesting start:
@@ -151,9 +149,9 @@ class module:
lutinMultiprocess.RunInPool(cmdLine, comment, file_cmd)
return file_dst
- ###############################################################################
- ## Commands for running gcc to compile a m file.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to compile a m file.
+ ##
def Compile_m_to_o(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.fileGenerateObject(binary,self.name,self.originFolder,file)
# create the command line befor requesting start:
@@ -184,9 +182,9 @@ class module:
lutinMultiprocess.RunInPool(cmdLine, comment, file_cmd)
return file_dst
- ###############################################################################
- ## Commands for running gcc to compile a C++ file.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to compile a C++ file.
+ ##
def Compile_xx_to_o(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.fileGenerateObject(binary,self.name,self.originFolder,file)
# create the command line befor requesting start:
@@ -216,9 +214,9 @@ class module:
lutinMultiprocess.RunInPool(cmdLine, comment, file_cmd)
return file_dst
- ###############################################################################
- ## Commands for running gcc to compile a C file.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to compile a C file.
+ ##
def Compile_cc_to_o(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.fileGenerateObject(binary,self.name,self.originFolder,file)
# create the command line befor requesting start:
@@ -246,9 +244,9 @@ class module:
return file_dst
- ###############################################################################
- ## Commands for running ar.
- ###############################################################################
+ ##
+ ## @brief Commands for running ar.
+ ##
def Link_to_a(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.GenerateFile(binary, self.name,self.originFolder,file,"lib-static")
#$(Q)$(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $(PRIVATE_ALL_OBJECTS)
@@ -280,9 +278,9 @@ class module:
return file_dst
- ###############################################################################
- ## Commands for running gcc to link a shared library.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to link a shared library.
+ ##
def Link_to_so(self, file, binary, target, depancy, libName=""):
if libName=="":
libName = self.name
@@ -300,8 +298,8 @@ class module:
target.global_flags_ld])
# check the dependency for this file :
- if False==dependency.NeedRePackage(file_dst, file_src, True, file_cmd, cmdLine) \
- and False==dependency.NeedRePackage(file_dst, depancy.src, False, file_cmd, cmdLine):
+ if dependency.NeedRePackage(file_dst, file_src, True, file_cmd, cmdLine) == False \
+ and dependency.NeedRePackage(file_dst, depancy.src, False, file_cmd, cmdLine) == False:
return tmpList[1]
lutinTools.CreateDirectoryOfFile(file_dst)
debug.printElement("SharedLib", libName, "==>", file_dst)
@@ -323,9 +321,9 @@ class module:
#debug.printElement("SharedLib", self.name, "==>", tmpList[1])
- ###############################################################################
- ## Commands for running gcc to link an executable.
- ###############################################################################
+ ##
+ ## @brief Commands for running gcc to link an executable.
+ ##
def Link_to_bin(self, file, binary, target, depancy):
file_src, file_dst, file_depend, file_cmd = target.GenerateFile(binary, self.name,self.originFolder,file,"bin")
#create comdLine :
@@ -362,26 +360,34 @@ class module:
lutinMultiprocess.StoreCommand(cmdLine, file_cmd)
- ###############################################################################
- ## Commands for copying files
- ###############################################################################
+ ##
+ ## @brief Commands for copying files
+ ##
def files_to_staging(self, binaryName, target):
for element in self.files:
debug.verbose("Might copy file : " + element[0] + " ==> " + element[1])
target.AddFileStaging(self.originFolder+"/"+element[0], element[1])
- ###############################################################################
- ## Commands for copying files
- ###############################################################################
+ ##
+ ## @brief Commands for copying files
+ ##
def folders_to_staging(self, binaryName, target):
for element in self.folders:
debug.verbose("Might copy folder : " + element[0] + "==>" + element[1])
lutinTools.CopyAnythingTarget(target, self.originFolder+"/"+element[0],element[1])
- ###############################################################################
- ## Create the module documentation:
- ###############################################################################
- def CreateDoc(self, target) :
+ ##
+ ## @brief Set the documentation availlable for this module
+ ##
+ def doc_enable(self):
+ self.docPath = lutinTools.GetCurrentPath(self.originFile)
+ self.documentation = lutinDoc.doc(self.name)
+
+ ##
+ ## @brief Create the module documentation:
+ ## @param[in,out] target target that request generation of the documentation
+ ##
+ def doc_parse_code(self, target):
if self.docPath == "":
return False
for root, dirnames, filenames in os.walk(self.docPath):
@@ -391,9 +397,28 @@ class module:
fileCompleteName = os.path.join(root, filename)
debug.debug(" Find a file : '" + fileCompleteName + "'")
self.documentation.add_file(fileCompleteName)
+
+ ##
+ ## @brief Generate real documentation files
+ ## @param[in,out] target target that request generation of the documentation
+ ##
+ def doc_generate(self, target):
+ if self.docPath == "":
+ return False
# Real creation of the documentation :
lutinTools.RemoveFolderAndSubFolder(target.GetDocFolder(self.name));
- self.documentation.generate_documantation(target.GetDocFolder(self.name))
+ self.documentation.generate_documantation(target, target.GetDocFolder(self.name))
+
+
+ ##
+ ## @brief Get link on a class or an enum in all the subclasses
+ ## @param[in] name of the class
+ ## @return [real element name, link on it]
+ ##
+ def doc_get_link(self, target, elementName):
+ if self.docPath == "":
+ return [elementName, ""]
+ return self.documentation.get_class_link_from_target(elementName);
# call here to build the module
diff --git a/lutinTarget.py b/lutinTarget.py
index 86f32a7..2718cc9 100644
--- a/lutinTarget.py
+++ b/lutinTarget.py
@@ -207,10 +207,18 @@ class Target:
self.LoadIfNeeded(modName)
def Build(self, name, packagesName=None):
- if name == "dump":
+ if name == "doc":
+ debug.info("Documentation for all")
+ self.LoadAll()
+ print 'Doc all modules'
+ for mod in self.moduleList:
+ mod.doc_parse_code(self)
+ for mod in self.moduleList:
+ mod.doc_generate(self)
+ elif name == "dump":
debug.info("dump all")
self.LoadAll()
- print 'Dump all module properties'
+ print 'Dump all modules properties'
for mod in self.moduleList:
mod.Display(self)
elif name == "all":
@@ -261,9 +269,23 @@ class Target:
return mod.Build(self, None)
elif actionName == "doc":
debug.debug("Create doc module '" + moduleName + "'")
- return mod.CreateDoc(self)
+ if mod.doc_parse_code(self) == False:
+ return False
+ return mod.doc_generate(self)
debug.error("not know module name : '" + moduleName + "' to '" + actionName + "' it")
+ ##
+ ## @brief Get link on a class or an enum in all the subclasses
+ ## @param[in] name of the class
+ ## @return [real element name, link on it]
+ ##
+ def doc_get_link(self, elementName):
+ for mod in self.moduleList:
+ elementRealName, link = mod.doc_get_link(self, elementName)
+ if len(link) != 0:
+ debug.verbose("find the element : " + elementName + " ==> " + link)
+ return [elementRealName, link]
+ return [elementName, ""]
__startTargetName="lutinTarget"