Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlava Risenberg2015-09-16 04:12:53 -0400
committerJeff Johnston2015-10-06 17:18:19 -0400
commit18d4e4b8cfa5d7793d671ca4b72fee62e1c5357c (patch)
tree0e7542a2f2f511bbfee2493c7db761bd01be093e
parent0458fa088c66423838679051676ae5f75502a042 (diff)
downloadorg.eclipse.linuxtools-stable-4.1.tar.gz
org.eclipse.linuxtools-stable-4.1.tar.xz
org.eclipse.linuxtools-stable-4.1.zip
Author: Slava Risenberg <slava@ezchip.com>stable-4.1
[447553] Added support for C code libhover metadata generated from Doxygen Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=447553 Signed-off-by: Slava Risenberg <slava@ezchip.com> Change-Id: I5935495681a805270a40c6c986ed3385721ad9af
-rw-r--r--libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/BuildFunctionInfos.java146
-rw-r--r--libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CDoxygenLibhoverGen.java667
-rw-r--r--libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CXmlLibhoverGen.java137
-rw-r--r--libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/LibhoverInfoGenerator.java39
4 files changed, 853 insertions, 136 deletions
diff --git a/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/BuildFunctionInfos.java b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/BuildFunctionInfos.java
index 33245f66c9..89b67272d5 100644
--- a/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/BuildFunctionInfos.java
+++ b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/BuildFunctionInfos.java
@@ -1,5 +1,6 @@
/*******************************************************************************
- * Copyright (c) 2009 Red Hat, Inc.
+ * Copyright (c) 2004, 2006, 2007, 2008, 2011, 2012 Red Hat, Inc.
+ * Copyright (c) 2015 Ezchip Semiconductor
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,14 +8,13 @@
*
* Contributors:
* Red Hat Incorporated - initial API and implementation
+ * EZchip Semiconductor - adding support for Doxygen XML files as input
*******************************************************************************/
package org.eclipse.linuxtools.internal.cdt.libhover.utils;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectOutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@@ -25,142 +25,17 @@ import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.linuxtools.cdt.libhover.FunctionInfo;
-import org.eclipse.linuxtools.cdt.libhover.LibHoverInfo;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class BuildFunctionInfos {
-
- private Document document;
- private LibHoverInfo hoverInfo = new LibHoverInfo();
-
- public BuildFunctionInfos(Document document) {
- this.document = document;
- }
-
- public Document getDocument() {
- return document;
- }
-
- private FunctionInfo getFunctionInfoFromNode(String name, Node functionNode, Document document) {
- FunctionInfo f = new FunctionInfo(name);
- NamedNodeMap functionNodeMap = functionNode.getAttributes();
- Node functionNodeReturntypeNode = functionNodeMap.item(0);
- String functionNodeRtName = functionNodeReturntypeNode.getNodeName();
-
- if (functionNodeRtName.equals("returntype")) { //$NON-NLS-1$
-
- // return type
-
- String functionNodeRtValue = functionNodeReturntypeNode.getNodeValue();
- f.setReturnType(functionNodeRtValue);
- } // returntype
-
- NodeList kids = functionNode.getChildNodes();
- for (int fnk = 0; fnk < kids.getLength(); fnk++) {
- Node kid = kids.item(fnk);
- String kidName = kid.getNodeName();
- if (kidName.equals("prototype")) { //$NON-NLS-1$
-
- // prototype
-
- String prototype = null;
-
- NodeList parms = kid.getChildNodes();
- for (int fnp = 0; fnp < parms.getLength(); fnp++) {
- Node parm = parms.item(fnp);
- String parmName = parm.getNodeName();
- if (parmName.equals("parameter")) { //$NON-NLS-1$
- NamedNodeMap parmMap = parm.getAttributes();
- Node parmNode = parmMap.item(0);
- String parameter = parmNode.getNodeValue();
- prototype = (null == prototype) ? parameter : prototype
- + ", " + parameter; //$NON-NLS-1$
- }
- }
- f.setPrototype(prototype);
- } // prototype
-
- else if (kidName.equals("headers")) { //$NON-NLS-1$
-
- // headers
-
- NodeList headers = kid.getChildNodes();
- for (int fnh = 0; fnh < headers.getLength(); fnh++) {
- Node header = headers.item(fnh);
- String headerName = header.getNodeName();
- if (headerName.equals("header")) { //$NON-NLS-1$
- NamedNodeMap headerMap = header.getAttributes();
- Node headerNode = headerMap.item(0);
- f.addHeader(headerNode.getNodeValue());
- }
- }
- } // headers
-
-
- else if (kidName.equals("groupsynopsis")) { //$NON-NLS-1$
-
- // group synopsis
-
- NamedNodeMap attr = kid.getAttributes();
- Node idnode = attr.getNamedItem("id"); //$NON-NLS-1$
- String id = idnode.getNodeValue();
- if (id != null) {
- Element elem2 = document.getElementById(id);
- if (null != elem2) {
- NodeList synopsisNode = elem2.getElementsByTagName("synopsis"); //$NON-NLS-1$
- if (null != synopsisNode && synopsisNode.getLength() > 0) {
- Node synopsis = synopsisNode.item(0);
- Node textNode = synopsis.getLastChild();
- f.setDescription(textNode.getNodeValue());
- }
- }
- }
- } else if (kidName.equals("synopsis")) { //$NON-NLS-1$
- // synopsis
- Node textNode = kid.getLastChild();
- f.setDescription(textNode.getNodeValue());
- }
- }
- return f;
- }
-
- private void buildCPPInfo(String fileName) {
- Document document = getDocument();
- NodeList nl = document.getElementsByTagName("construct"); //$NON-NLS-1$
- for (int i = 0; i < nl.getLength(); ++i) {
- Node n = nl.item(i);
- NamedNodeMap m = n.getAttributes();
- Node id = m.getNamedItem("id"); //$NON-NLS-1$
- if (id != null && id.getNodeValue().startsWith("function-")) { //$NON-NLS-1$
- String name = id.getNodeValue().substring(9);
- NodeList nl2 = n.getChildNodes();
- for (int j = 0; j < nl2.getLength(); ++j) {
- Node n2 = nl2.item(j);
- if (n2.getNodeName().equals("function")) { //$NON-NLS-1$
- FunctionInfo f = getFunctionInfoFromNode(name, n2, document);
- hoverInfo.functions.put(name, f);
- }
- }
- }
- }
- try (FileOutputStream f = new FileOutputStream(fileName);
- ObjectOutputStream out = new ObjectOutputStream(f)){
- // Now, output the LibHoverInfo for caching later
- out.writeObject(hoverInfo);
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
+
+ private static final String IS_DOXYGEN = "--doxygen"; //$NON-NLS-1$
/**
* @param args args[0] - URL or file name of xml document to parse
* args[1] - file name to place resultant serialized LibHoverInfo
+ * args[2] - optional parameter in form of '--doxygen' whether provided XML file in doxygen format
*/
public static void main(String[] args) {
URI acDoc;
@@ -174,19 +49,18 @@ public class BuildFunctionInfos {
} else {
docStream = new FileInputStream(p.toFile());
}
+
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(docStream);
- if (doc != null) {
- BuildFunctionInfos d = new BuildFunctionInfos(doc);
- d.buildCPPInfo(args[1]);
- }
+ LibhoverInfoGenerator libhoverInfoGenerator = (args.length == 3 && IS_DOXYGEN.equals(args[2]))?new CDoxygenLibhoverGen(doc):new CXmlLibhoverGen(doc);
+ libhoverInfoGenerator.generate(args[1]);
+
System.out.println("Built " + args[1] + " from " + args[0]); //$NON-NLS-1$ //$NON-NLS-2$
} catch (URISyntaxException|SAXException|ParserConfigurationException|IOException e) {
e.printStackTrace();
}
}
-
}
diff --git a/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CDoxygenLibhoverGen.java b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CDoxygenLibhoverGen.java
new file mode 100644
index 0000000000..9ae7ed5323
--- /dev/null
+++ b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CDoxygenLibhoverGen.java
@@ -0,0 +1,667 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat, Inc.
+ * Copyright (c) 2015 Ezchip Semiconductor
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * EZchip Semiconductor - adding support for Doxygen XML files as input
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.libhover.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.cdt.libhover.ClassInfo;
+import org.eclipse.linuxtools.cdt.libhover.FunctionInfo;
+import org.eclipse.linuxtools.cdt.libhover.LibHoverInfo;
+import org.eclipse.linuxtools.cdt.libhover.MemberInfo;
+import org.eclipse.linuxtools.cdt.libhover.TypedefInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class CDoxygenLibhoverGen extends LibhoverInfoGenerator{
+
+ private static final String PROT3 = "prot";//$NON-NLS-1$
+ private static final String RETURN = "return";//$NON-NLS-1$
+ private static final String PARAMETERDESCRIPTION = "parameterdescription";//$NON-NLS-1$
+ private static final String PARAMETERNAME = "parametername";//$NON-NLS-1$
+ private static final String PARAMETERNAMELIST = "parameternamelist";//$NON-NLS-1$
+ private static final String PARAMETERITEM = "parameteritem";//$NON-NLS-1$
+ private static final String EXCEPTION = "exception";//$NON-NLS-1$
+ private static final String DEFINITION = "definition";//$NON-NLS-1$
+ private static final String TYPEDEF2 = "typedef";//$NON-NLS-1$
+ private static final String REFID2 = "refid";//$NON-NLS-1$
+ private static final String REF = "ref";//$NON-NLS-1$
+ private static final String PUBLIC_FUNC = "public-func";//$NON-NLS-1$
+ private static final String BASECOMPOUNDREF = "basecompoundref";//$NON-NLS-1$
+ private static final String INCLUDES = "includes";//$NON-NLS-1$
+ private static final String DECLNAME = "declname";//$NON-NLS-1$
+ private static final String TEMPLATEPARAMLIST = "templateparamlist";//$NON-NLS-1$
+ private static final String CLASS = "class";//$NON-NLS-1$
+ private static final String PUBLIC = "public";//$NON-NLS-1$
+ private static final String LOCATION = "location";//$NON-NLS-1$
+ private static final String SIMPLESECT = "simplesect";//$NON-NLS-1$
+ private static final String PARAMETERLIST = "parameterlist";//$NON-NLS-1$
+ private static final String DETAILEDDESCRIPTION = "detaileddescription";//$NON-NLS-1$
+ private static final String PARA = "para";//$NON-NLS-1$
+ private static final String BRIEFDESCRIPTION = "briefdescription";//$NON-NLS-1$
+ private static final String TYPE2 = "type";//$NON-NLS-1$
+ private static final String PARAM = "param";//$NON-NLS-1$
+ private static final String ARGSSTRING = "argsstring";//$NON-NLS-1$
+ private static final String NAME3 = "name";//$NON-NLS-1$
+ private static final String FUNCTION = "function";//$NON-NLS-1$
+ private static final String MEMBERDEF = "memberdef";//$NON-NLS-1$
+ private static final String FUNC = "func";//$NON-NLS-1$
+ private static final String SECTIONDEF = "sectiondef";//$NON-NLS-1$
+ private static final String COMPOUNDNAME = "compoundname";//$NON-NLS-1$
+ private static final String FILE = "file";//$NON-NLS-1$
+ private static final String COMPOUNDDEF = "compounddef";//$NON-NLS-1$
+ private static final String TYPEDEF = "typedef ";//$NON-NLS-1$
+ private Document document;
+ private Map<String, ClassInfo> classesById = new HashMap<>();
+
+ public CDoxygenLibhoverGen(Document document) {
+ this.document = document;
+ }
+
+ private String[] getTypedefTypes(String def) {
+ String[] result = null;
+ if (def.startsWith(TYPEDEF)) {
+ int startIndex = 8;
+ int count = 0;
+ int i = def.length() - 1;
+ // To break up types, we look for first blank outside of a template, working backwards.
+ // We need to work backwards because the transformed type may contain actual numeric parameters
+ // which could use the shift operators and we won't know whether they are shift operators or
+ // template specifiers without some actual parsing.
+ while (i >= 0) {
+ char ch = def.charAt(i);
+ if (ch == '<') {
+ --count;
+ } else if (ch == '>') {
+ ++count;
+ }
+ // We look at last blank not in a template as being the delimeter between
+ // type name and definition.
+ if (count == 0 && ch == ' ') {
+ startIndex = i + 1;
+ break;
+ }
+ --i;
+ }
+ result = new String[2];
+ result[1] = def.substring(startIndex);
+ // Following is a bit of a hack knowing the docs don't add the namespace when the transformed
+ // type is in the same space
+ int namespace = result[1].indexOf("::"); //$NON-NLS-1$
+ if (namespace < 0) {
+ result[0] = def.substring(8, startIndex).trim();
+ } else {
+ result[0] = result[1].substring(0, namespace) + "::" + def.substring(8, startIndex).trim(); //$NON-NLS-1$
+ }
+ }
+ return result;
+ }
+
+ private String getElementText(Node node) {
+ StringBuffer d = new StringBuffer();
+ NodeList nl = node.getChildNodes();
+ for (int x = 0; x < nl.getLength(); ++x) {
+ Node text = nl.item(x);
+ if (text.getNodeType() == Node.TEXT_NODE) {
+ d.append(text.getNodeValue());
+ } else {
+ d.append(getElementText(text));
+ }
+ }
+ return d.toString();
+ }
+
+ private ClassInfo getClassInfo(LibHoverInfo libHoverInfo, String className) {
+ String typedefName = className.replaceAll("<.*>", "<>"); //$NON-NLS-1$ //$NON-NLS-2$
+ TypedefInfo typedef = libHoverInfo.typedefs.get(typedefName);
+ if (typedef != null) {
+ className = typedef.getTransformedType(className); // Reset class name to typedef transformation
+ }
+ int index = className.indexOf('<');
+ // Check if it is a template reference.
+ if (index != -1) {
+ // It is. We want to see if there are partial specific templates
+ // and we choose the first match. If nothing matches our particular
+ // case, we fall back on the initial generic template.
+ ClassInfo info = libHoverInfo.classes.get(className.substring(0, index));
+ if (info == null)
+ return null;
+ ArrayList<ClassInfo> children = info.getChildren();
+ if (children != null && children.size() > 0) {
+ for (int x = 0; x < children.size(); ++x) {
+ ClassInfo child = children.get(x);
+ if (className.matches(child.getClassName())) {
+ info = child;
+ break;
+ }
+ }
+ }
+ return info;
+ }
+ // Otherwise no template, just fetch the class info directly.
+ return libHoverInfo.classes.get(className);
+ }
+
+ @Override
+ public LibHoverInfo doGenerate(){
+ LibHoverInfo libHoverInfo = new LibHoverInfo();
+ // Create a hash table of all the class nodes mapped by class name. Trim any template info
+ // for the class name key value.
+ NodeList nl = document.getElementsByTagName(COMPOUNDDEF);
+ for (int i = 0; i < nl.getLength(); ++i) {
+ Node n = nl.item(i);
+ NamedNodeMap attrs = n.getAttributes();
+ Node kind = attrs.getNamedItem("kind"); //$NON-NLS-1$
+ Node id = attrs.getNamedItem("id"); //$NON-NLS-1$
+ Node prot = attrs.getNamedItem(PROT3);
+
+ // C functions
+ if (id != null && kind != null && FILE.equals(kind.getNodeValue())) {
+ NodeList nl2 = n.getChildNodes();
+ FunctionInfo fi = null;
+ String include = null;
+ for (int j = 0; j < nl2.getLength(); ++j) {
+ Node n2 = nl2.item(j);
+ String name2 = n2.getNodeName();
+
+ if (COMPOUNDNAME.equals(name2)) {
+ // compoundname for a file node is the filename
+ // this can be a .c or .h file
+ String filename = getElementText(n2);
+ if(filename.endsWith(".h")) { //$NON-NLS-1$
+ include = filename;
+ }
+ } else if (SECTIONDEF.equals(name2)) {
+ // We are only interested in functions
+ NamedNodeMap m = n2.getAttributes();
+ if (m != null) {
+ Node kind2 = m.getNamedItem("kind"); //$NON-NLS-1$
+ if (kind2 != null && FUNC.equals(kind2.getNodeValue())) {
+ NodeList pubfuncs = n2.getChildNodes();
+ int pubfuncLength = pubfuncs.getLength();
+ for (int j1 = 0; j1 < pubfuncLength; ++j1) {
+ Node n3 = pubfuncs.item(j1);
+ // Add all public member functions to the list of members
+ if (MEMBERDEF.equals(n3.getNodeName())) {
+ NamedNodeMap m3 = n3.getAttributes();
+ if (m3 != null) {
+ Node m3Kind = m3.getNamedItem("kind"); //$NON-NLS-1$
+ if (m3Kind != null && FUNCTION.equals(m3Kind.getNodeValue())) {
+ String name = null;
+ String type = null;
+ String args = null;
+ String desc = null;
+
+ boolean briefDescriptionProcessed = false;
+ boolean detailedDescriptionProcessed = false;
+ boolean parameterListProcessed = false;
+ boolean retValProcessed = false;
+ boolean locationProcessed = false;
+
+ ArrayList<String> parms = new ArrayList<>();
+ NodeList nl4 = n3.getChildNodes();
+ int memberLength = nl4.getLength();
+ for (int k = 0; k < memberLength; ++k) {
+ Node n4 = nl4.item(k);
+ String n4Name = n4.getNodeName();
+ if (TYPE2.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ type = ""; //$NON-NLS-1$
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (n5.getNodeType() == Node.TEXT_NODE)
+ type += n5.getNodeValue();
+ }
+ } else if (NAME3.equals(n4Name)) {
+ name = n4.getTextContent();
+ } else if (ARGSSTRING.equals(n4Name)) {
+ args = getElementText(n4);
+ } else if (PARAM.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (TYPE2.equals(n5.getNodeName())) {
+ parms.add(getElementText(n5));
+ }
+ }
+ } else if (BRIEFDESCRIPTION.equals(n4Name) && !briefDescriptionProcessed ) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (PARA.equals(n5.getNodeName())) {
+ if (desc == null) {
+ desc = ""; //$NON-NLS-1$
+ }
+ desc += "<p>" + getElementText(n5) + "</p>"; //$NON-NLS-1$ //$NON-NLS-2$
+ briefDescriptionProcessed = true;
+ }
+ }
+ } else if (DETAILEDDESCRIPTION.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (n5.getNodeName().equals(PARA)) {
+ if (desc == null)
+ desc = new String(""); //$NON-NLS-1$
+ NodeList nl6 = n5.getChildNodes();
+ Node n6 = nl6.item(0);
+ if (n6.getNodeType() == Node.TEXT_NODE && !detailedDescriptionProcessed){
+ desc += "<p>" + getElementText(n5) + "</p>"; //$NON-NLS-1$ //$NON-NLS-2$
+ detailedDescriptionProcessed = true;
+ } else {
+ for (int x2 = 0; x2 < nl6.getLength(); ++x2) {
+ n6 = nl6.item(x2);
+ if (PARAMETERLIST.equals(n6.getNodeName()) && !parameterListProcessed) {
+ desc += getParameters(n6, false);
+ parameterListProcessed = true;
+ } else if (SIMPLESECT.equals(n6.getNodeName()) & !retValProcessed) {
+ desc += getReturn(n6);
+ retValProcessed = true;
+ }
+ }
+ }
+ }
+ }
+ } else if (LOCATION.equals(n4Name) && !locationProcessed) {
+ // Location is after all descriptions so we can now add the function
+ if (name != null) {
+ // Try to update existing function, in case information is split between .c and .h files
+ fi = libHoverInfo.functions.get(name);
+ if (fi == null) {
+ fi = new FunctionInfo(name);
+ }
+ if (type != null) {
+ fi.setReturnType(type);
+ }
+ if (args != null) {
+ // Strip ()s, as the plugin adds them back in
+ if(args.charAt(0) == '(' && args.charAt(args.length() - 1) == ')')
+ fi.setPrototype(args.substring(1, args.length() - 1));
+ else
+ fi.setPrototype(args);
+ }
+ if (desc != null) {
+ fi.setDescription(desc);
+ }
+ if(include != null) {
+ fi.addHeader(include);
+ }
+ //System.out.println(name + "|" + type + "|" + args + "|" + desc + "|" + include);
+ libHoverInfo.functions.put(name, fi);
+ locationProcessed = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // We are only interested in cataloging public classes.
+ if (id != null && prot != null && PUBLIC.equals(prot.getNodeValue())
+ && kind != null && CLASS.equals(kind.getNodeValue())) {
+ NodeList nl2 = n.getChildNodes();
+ ClassInfo d = null;
+ String hashName = null;
+ for (int j = 0; j < nl2.getLength(); ++j) {
+ Node n2 = nl2.item(j);
+ String name2 = n2.getNodeName();
+ if (name2.equals(COMPOUNDNAME)) {
+ String text = n2.getTextContent();
+ if (text != null && !text.equals("")) { //$NON-NLS-1$
+ String className = text;
+ text = text.replaceAll("<\\s*", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+ text = text.replaceAll("\\s*>", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+ int index = text.indexOf('<');
+ hashName = text;
+ if (index > 0)
+ hashName = text.substring(0, index);
+ d = new ClassInfo(className, n);
+ classesById.put(id.getNodeValue(), d);
+ ClassInfo e = libHoverInfo.classes.get(hashName);
+ if (e != null) { /* We are dealing with a partial specific template...add it to list */
+ if (!d.areTemplateParmsFilled())
+ d.setTemplateParms(getTemplateParms(n));
+ String[] templateParms = d.getTemplateParms();
+ // For each template parameter, replace with a generic regex so later we can compare
+ // and identify a match (e.g. A<_a, _b> and A<char, _b> are defined and we have an instance
+ // of A<char, int>. We want to to match with A<char, _b> and replace all occurrences of "_b"
+ // with "int". For speed, we assume that the template parameter is not a subset of any
+ // other variable (e.g. if _A is used, there is no __A or _AB). If this proves untrue in
+ // any instance, more refinement of the initial value to replace will be required.
+ for (int k = 0; k < templateParms.length; ++k) {
+ text = text.replaceAll(templateParms[k], "[a-zA-Z0-9_: *]+"); //$NON-NLS-1$
+ }
+ d.setClassName(text);
+ e.addTemplate(d);
+ }
+ else
+ libHoverInfo.classes.put(hashName, d);
+ }
+ } else if (TEMPLATEPARAMLIST.equals(name2)) {
+ ArrayList<String> templates = new ArrayList<>();
+ NodeList params = n2.getChildNodes();
+ int paramsLength = params.getLength();
+ for (int j2 = 0; j2 < paramsLength; ++j2) {
+ Node n3 = params.item(j2);
+ if (n3.getNodeName().equals(PARAM)) {
+ NodeList types = n3.getChildNodes();
+ int typesLength = types.getLength();
+ for (int j3 = 0; j3 < typesLength; ++j3) {
+ Node n4 = types.item(j3);
+ if (DECLNAME.equals(n4.getNodeName())) {
+ templates.add(getElementText(n4));
+ }
+ }
+ }
+ }
+ String[] templateNames = new String[templates.size()];
+ d.setTemplateParms(templates.toArray(templateNames));
+ } else if (INCLUDES.equals(name2)) {
+ String include = getElementText(n2);
+ if (d != null)
+ d.setInclude(include);
+ } else if (BASECOMPOUNDREF.equals(name2)) {
+ // We have a base class. If public, add it to the list of nodes to look at in case we don't find the member
+ // in the current class definition.
+ NamedNodeMap m = n2.getAttributes();
+ if (m != null) {
+ Node refid = m.getNamedItem(REFID2);
+ Node prot2 = m.getNamedItem(PROT3);
+ if (prot2 != null && PUBLIC.equals(prot2.getNodeValue())) {
+ ClassInfo baseClass = null;
+ if (refid != null) {
+ // If we have been given the id of the base class, fetch it directly
+ baseClass = classesById.get(refid.getNodeValue());
+ } else {
+ // We probably have a template that needs resolution
+ String baseClassName = n2.getTextContent();
+// System.out.println("base class name is " + baseClassName);
+ baseClass = getClassInfo(libHoverInfo, baseClassName);
+ }
+ if (d != null && baseClass != null)
+ d.addBaseClass(baseClass);
+ }
+ }
+ } else if (SECTIONDEF.equals(name2)) {
+ // We are only interested in public member functions which are in their own section.
+ NamedNodeMap m = n2.getAttributes();
+ if (m != null) {
+ Node kind2 = m.getNamedItem("kind"); //$NON-NLS-1$
+ if (kind2 != null && PUBLIC_FUNC.equals(kind2.getNodeValue())) {
+ NodeList pubfuncs = n2.getChildNodes();
+ int pubfuncLength = pubfuncs.getLength();
+ for (int j1 = 0; j1 < pubfuncLength; ++j1) {
+ Node n3 = pubfuncs.item(j1);
+ // Add all public member functions to the list of members
+ if (MEMBERDEF.equals(n3.getNodeName())) {
+ NamedNodeMap m3 = n3.getAttributes();
+ if (m3 != null) {
+ Node m3Kind = m3.getNamedItem("kind"); //$NON-NLS-1$
+ if (m3Kind != null && FUNCTION.equals(m3Kind.getNodeValue())) {
+ String name = null;
+ String type = null;
+ String args = null;
+ String desc = null;
+ ArrayList<String> parms = new ArrayList<>();
+ NodeList nl4 = n3.getChildNodes();
+ int memberLength = nl4.getLength();
+ for (int k = 0; k < memberLength; ++k) {
+ Node n4 = nl4.item(k);
+ String n4Name = n4.getNodeName();
+ if (TYPE2.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ type = ""; //$NON-NLS-1$
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (n5.getNodeType() == Node.TEXT_NODE)
+ type += n5.getNodeValue();
+ else if (REF.equals(n5.getNodeName())) {
+ NamedNodeMap n5m = n5.getAttributes();
+ Node n5id = n5m.getNamedItem(REFID2);
+ if (n5id != null) {
+ String refid = n5id.getNodeValue();
+ ClassInfo refClass = classesById.get(refid);
+ if (refClass != null)
+ type += refClass.getClassName();
+ }
+ }
+ }
+ } else if (NAME3.equals(n4Name)) {
+ name = n4.getTextContent();
+ } else if (ARGSSTRING.equals(n4Name)) {
+ args = getElementText(n4);
+ } else if (PARAM.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (TYPE2.equals(n5.getNodeName())) {
+ parms.add(getElementText(n5));
+ }
+ }
+ } else if (BRIEFDESCRIPTION.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (PARA.equals(n5.getNodeName())) {
+ if (desc == null) {
+ desc = ""; //$NON-NLS-1$
+ }
+ desc += "<p>" + getElementText(n5) + "</p>"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ } else if (DETAILEDDESCRIPTION.equals(n4Name)) {
+ NodeList nl5 = n4.getChildNodes();
+ for (int x = 0; x < nl5.getLength(); ++x) {
+ Node n5 = nl5.item(x);
+ if (PARA.equals(n5.getNodeName())) {
+ if (desc == null)
+ desc = new String(""); //$NON-NLS-1$
+ NodeList nl6 = n5.getChildNodes();
+ Node n6 = nl6.item(0);
+ if (n6.getNodeType() == Node.TEXT_NODE)
+ desc += "<p>" + getElementText(n5) + "</p>"; //$NON-NLS-1$ //$NON-NLS-2$
+ else {
+ for (int x2 = 0; x2 < nl6.getLength(); ++x2) {
+ n6 = nl6.item(x2);
+ if (PARAMETERLIST.equals(n6.getNodeName())) {
+ desc += getParameters(n6, true);
+ } else if (SIMPLESECT.equals(n6.getNodeName())) {
+ desc += getReturn(n6);
+ }
+ }
+ }
+ }
+ }
+ } else if (LOCATION.equals(n4Name)) {
+ // Location is after all descriptions so we can now add the member
+ if (name != null) {
+ MemberInfo member = new MemberInfo(name);
+ member.setReturnType(type);
+ member.setPrototype(args);
+ member.setDescription(desc);
+ String[] argNames = new String[parms.size()];
+ member.setParamTypes(parms.toArray(argNames));
+ d.addMember(member);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // Create a hash table of all the typedefs. Keep any template info.
+ nl = document.getElementsByTagName(MEMBERDEF);
+ for (int i = 0; i < nl.getLength(); ++i) {
+ Node n = nl.item(i);
+ NamedNodeMap attrs = n.getAttributes();
+ if (attrs != null) {
+ Node kind = attrs.getNamedItem("kind"); //$NON-NLS-1$
+ Node prot = attrs.getNamedItem(PROT3);
+ if (kind != null && TYPEDEF2.equals(kind.getNodeValue())
+ && prot != null && PUBLIC.equals(prot.getNodeValue())) {
+ NodeList list = n.getChildNodes();
+ for (int x = 0; x < list.getLength(); ++x) {
+ Node n2 = list.item(x);
+ if (DEFINITION.equals(n2.getNodeName())) {
+ String def = n2.getTextContent();
+ if (def != null && !def.equals("")) { //$NON-NLS-1$
+ def = def.replaceAll("<\\s*", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+ def = def.replaceAll("\\s*>", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+ String[] types = getTypedefTypes(def);
+ if(types == null){
+ continue;
+ }
+ TypedefInfo d = new TypedefInfo(types[1], types[0]);
+ String hashName = d.getTypedefName();
+ int index = hashName.indexOf('<');
+ if (index > 0) {
+ String className = hashName.substring(0, index);
+ hashName = hashName.replaceAll("<.*>", "<>"); //$NON-NLS-1$ //$NON-NLS-2$
+ ClassInfo e = libHoverInfo.classes.get(className);
+ if (e == null)
+ break;
+ ArrayList<ClassInfo> children = e.getChildren();
+ if (children != null && children.size() > 0) {
+ for (int y = 0; y < children.size(); ++y) {
+ ClassInfo child = children.get(y);
+ String childName = child.getClassName().replaceAll("\\*", "\\\\*"); //$NON-NLS-1$ //$NON-NLS-2$
+ childName = childName.replace("[]", "\\[\\]"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (types[1].matches(childName.concat("::.*"))) { //$NON-NLS-1$
+ e = child;
+ break;
+ }
+ }
+ }
+ String[] templates = e.getTemplateParms();
+ d.copyTemplates(templates);
+
+ TypedefInfo f = libHoverInfo.typedefs.get(hashName);
+ if (f != null) {
+ String typedefName = d.getTypedefName();
+ for (int z = 0; z < templates.length; ++z) {
+ typedefName = typedefName.replaceAll(templates[z], "[a-zA-Z0-9_: ]+"); //$NON-NLS-1$
+ }
+ d.setTypedefName(typedefName);
+ f.addTypedef(d);
+ }
+ else
+ libHoverInfo.typedefs.put(hashName, d);
+ break;
+ } else {
+ // Otherwise we have a non-template typedef name. Just add it to the list.
+ libHoverInfo.typedefs.put(hashName, d);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return libHoverInfo;
+ }
+
+ private String getParameters(Node n6, boolean addHyphen) {
+ String desc = "<br><br><h3>Parameters:</h3>"; //$NON-NLS-1$
+ NamedNodeMap m = n6.getAttributes();
+ Node kind = m.getNamedItem("kind"); //$NON-NLS-1$
+ if (kind != null && EXCEPTION.equals(kind.getNodeValue())) {
+ desc = "<br><br><h3>Exceptions:</h3>"; //$NON-NLS-1$
+ }
+ NodeList nl = n6.getChildNodes();
+ for (int x = 0; x < nl.getLength(); ++x) {
+ Node n = nl.item(x);
+ if (PARAMETERITEM.equals(n.getNodeName())) {
+ NodeList nl2 = n.getChildNodes();
+ for (int y = 0; y < nl2.getLength(); ++y) {
+ Node n2 = nl2.item(y);
+ if (PARAMETERNAMELIST.equals(n2.getNodeName())) {
+ NodeList nl3 = n2.getChildNodes();
+ for (int z = 0; z < nl3.getLength(); ++z) {
+ Node n3 = nl3.item(z);
+ if (PARAMETERNAME.equals(n3.getNodeName())) {
+ desc += getElementText(n3);
+ if(addHyphen) {
+ desc += " - ";//$NON-NLS-1$
+ }
+ }
+ }
+ } else if (PARAMETERDESCRIPTION.equals(n2.getNodeName())) {
+ desc += getElementText(n2) + "<br>"; //$NON-NLS-1$
+ }
+
+ }
+ }
+ }
+ return desc;
+
+ }
+
+ private String getReturn(Node n6) {
+ String desc = ""; //$NON-NLS-1$
+ NamedNodeMap m = n6.getAttributes();
+ Node kind = m.getNamedItem("kind"); //$NON-NLS-1$
+ if (kind != null && RETURN.equals(kind.getNodeValue())) {
+ desc += "<br><h3>Returns:</h3>" + getElementText(n6) + "<br>"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return desc;
+ }
+
+ private String[] getTemplateParms(Node classNode) {
+ Node n = null;
+ ArrayList<String> templateArray = new ArrayList<>();
+ NodeList list = classNode.getChildNodes();
+ for (int i = 0; i < list.getLength(); ++i) {
+ n = list.item(i);
+ if (TEMPLATEPARAMLIST.equals(n.getNodeName())) {
+ break;
+ }
+ }
+ if (n != null) {
+ NodeList templateList = n.getChildNodes();
+ for (int j = 0; j < templateList.getLength(); ++j) {
+ Node p = templateList.item(j);
+ if (PARAM.equals(p.getNodeName())) {
+ NodeList paramList = p.getChildNodes();
+ for (int k = 0; k < paramList.getLength(); ++k) {
+ Node q = paramList.item(k);
+ if (DECLNAME.equals(q.getNodeName())) {
+ String templateName = q.getTextContent();
+ templateArray.add(templateName);
+ }
+ }
+ }
+ }
+ }
+ String[] templates = new String[templateArray.size()];
+ return templateArray.toArray(templates);
+ }
+}
diff --git a/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CXmlLibhoverGen.java b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CXmlLibhoverGen.java
new file mode 100644
index 0000000000..283ea08e40
--- /dev/null
+++ b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/CXmlLibhoverGen.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Red Hat, Inc.
+ * Copyright (c) 2015 Ezchip Semiconductor
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * EZchip Semiconductor - adding support for Doxygen XML files as input
+ * Red Hat Incorporated - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.libhover.utils;
+
+import org.eclipse.linuxtools.cdt.libhover.FunctionInfo;
+import org.eclipse.linuxtools.cdt.libhover.LibHoverInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class CXmlLibhoverGen extends LibhoverInfoGenerator{
+
+ public CXmlLibhoverGen(Document document){
+ this.document = document;
+ }
+
+ private FunctionInfo getFunctionInfoFromNode(String name, Node functionNode, Document document) {
+ FunctionInfo f = new FunctionInfo(name);
+ NamedNodeMap functionNodeMap = functionNode.getAttributes();
+ Node functionNodeReturntypeNode = functionNodeMap.item(0);
+ String functionNodeRtName = functionNodeReturntypeNode.getNodeName();
+
+ if (functionNodeRtName.equals("returntype")) { //$NON-NLS-1$
+
+ // return type
+
+ String functionNodeRtValue = functionNodeReturntypeNode.getNodeValue();
+ f.setReturnType(functionNodeRtValue);
+ } // returntype
+
+ NodeList kids = functionNode.getChildNodes();
+ for (int fnk = 0; fnk < kids.getLength(); fnk++) {
+ Node kid = kids.item(fnk);
+ String kidName = kid.getNodeName();
+ if (kidName.equals("prototype")) { //$NON-NLS-1$
+
+ // prototype
+
+ String prototype = null;
+
+ NodeList parms = kid.getChildNodes();
+ for (int fnp = 0; fnp < parms.getLength(); fnp++) {
+ Node parm = parms.item(fnp);
+ String parmName = parm.getNodeName();
+ if (parmName.equals("parameter")) { //$NON-NLS-1$
+ NamedNodeMap parmMap = parm.getAttributes();
+ Node parmNode = parmMap.item(0);
+ String parameter = parmNode.getNodeValue();
+ prototype = (null == prototype) ? parameter : prototype
+ + ", " + parameter; //$NON-NLS-1$
+ }
+ }
+ f.setPrototype(prototype);
+ } // prototype
+
+ else if (kidName.equals("headers")) { //$NON-NLS-1$
+
+ // headers
+
+ NodeList headers = kid.getChildNodes();
+ for (int fnh = 0; fnh < headers.getLength(); fnh++) {
+ Node header = headers.item(fnh);
+ String headerName = header.getNodeName();
+ if (headerName.equals("header")) { //$NON-NLS-1$
+ NamedNodeMap headerMap = header.getAttributes();
+ Node headerNode = headerMap.item(0);
+ f.addHeader(headerNode.getNodeValue());
+ }
+ }
+ } // headers
+
+
+ else if (kidName.equals("groupsynopsis")) { //$NON-NLS-1$
+
+ // group synopsis
+
+ NamedNodeMap attr = kid.getAttributes();
+ Node idnode = attr.getNamedItem("id"); //$NON-NLS-1$
+ String id = idnode.getNodeValue();
+ if (id != null) {
+ Element elem2 = document.getElementById(id);
+ if (null != elem2) {
+ NodeList synopsisNode = elem2.getElementsByTagName("synopsis"); //$NON-NLS-1$
+ if (null != synopsisNode && synopsisNode.getLength() > 0) {
+ Node synopsis = synopsisNode.item(0);
+ Node textNode = synopsis.getLastChild();
+ f.setDescription(textNode.getNodeValue());
+ }
+ }
+ }
+ } else if (kidName.equals("synopsis")) { //$NON-NLS-1$
+ // synopsis
+ Node textNode = kid.getLastChild();
+ f.setDescription(textNode.getNodeValue());
+ }
+ }
+ return f;
+ }
+
+ @Override
+ protected LibHoverInfo doGenerate() {
+ LibHoverInfo hoverInfo = new LibHoverInfo();
+
+ NodeList nl = document.getElementsByTagName("construct"); //$NON-NLS-1$
+ for (int i = 0; i < nl.getLength(); ++i) {
+ Node n = nl.item(i);
+ NamedNodeMap m = n.getAttributes();
+ Node id = m.getNamedItem("id"); //$NON-NLS-1$
+ if (id != null && id.getNodeValue().startsWith("function-")) { //$NON-NLS-1$
+ String name = id.getNodeValue().substring(9);
+ NodeList nl2 = n.getChildNodes();
+ for (int j = 0; j < nl2.getLength(); ++j) {
+ Node n2 = nl2.item(j);
+ if (n2.getNodeName().equals("function")) { //$NON-NLS-1$
+ FunctionInfo f = getFunctionInfoFromNode(name, n2, document);
+ hoverInfo.functions.put(name, f);
+ }
+ }
+ }
+ }
+
+ return hoverInfo;
+ }
+
+}
diff --git a/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/LibhoverInfoGenerator.java b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/LibhoverInfoGenerator.java
new file mode 100644
index 0000000000..ebd1ff23ee
--- /dev/null
+++ b/libhover/org.eclipse.linuxtools.cdt.libhover/src/org/eclipse/linuxtools/internal/cdt/libhover/utils/LibhoverInfoGenerator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EZChip Semiconductor
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Slava Risenberg <slava@ezchip.com> - adding support for Doxygen XML files as input
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.cdt.libhover.utils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.eclipse.linuxtools.cdt.libhover.LibHoverInfo;
+import org.w3c.dom.Document;
+
+public abstract class LibhoverInfoGenerator {
+
+ protected Document document;
+
+ public void generate(String outputFile){
+ LibHoverInfo hoverInfo = doGenerate();
+ save(hoverInfo, outputFile);
+ }
+
+ protected abstract LibHoverInfo doGenerate();
+
+ protected void save(LibHoverInfo hoverInfo, String fileName){
+ try (FileOutputStream f = new FileOutputStream(fileName);
+ ObjectOutputStream out = new ObjectOutputStream(f)) {
+ out.writeObject(hoverInfo);
+ }catch(IOException ioException){
+ ioException.printStackTrace();
+ }
+ }
+}

Back to the top