Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Linux Tools Project/Libhover/Developers Guide"

(C++ Library Hover)
(C++ Library Hover)
Line 211: Line 211:
 
* desc - member description in html format
 
* desc - member description in html format
 
* returnType - the return type of the member function
 
* returnType - the return type of the member function
* paramTypes - an array of the parameter types of this function
+
* paramTypes - an array of just the parameter types of this function without template replacement.  The array is used in conjunction with template types to verify we have the correct member being used (e.g. a(_T, _U) of A<_T, _U> is a match for a(Integer k, Double l) of A<Integer, Double> class).
 
* children - members with the same name as this (i.e. overloaded method signatures)
 
* children - members with the same name as this (i.e. overloaded method signatures)

Revision as of 19:49, 24 February 2011

{{#eclipseproject:technology.linux-distros}}

Linux Tools
Website
Download
Community
Mailing ListForumsIRCmattermost
Issues
OpenHelp WantedBug Day
Contribute
Browse Source

Introduction

The Libhover plug-in from the Linux Tools project provides a common interface for supplying C and C++ hover help for libraries. The plug-in uses a CDT (C/C++ Developer Tools) Help extension to register itself with the CDT. When a C or C++ file is presented in the editor and a hover event occurs, the CDT will call the Libhover plug-in to get information. In turn, the Libhover plug-in supplies its own extension which allows the end-user to specify a set of valid hovers to use. Each hover library can be enabled or disabled for a C/C++ project via the Project->Properties->C/C++ General->Documentation page. There a list of the valid hovers are shown and the user can check or un-check them as desired. Note that Libhover help suppliers set the language of the hover help and so a C project will ignore any C++ hover libraries. For a C++ project, both C and C++ library hovers are valid so they will all appear on the Documentation page.

Libhover Extension

The Libhover plug-in adds a new org.eclipse.linuxtools.cdt.libhover.library extension to be used in a plug-in. Let's examine an example which specifies libhover help for the glibc C Library:

  <extension
        id="library"
        name="Glibc C Library"
        point="org.eclipse.linuxtools.cdt.libhover.library">
     <library
           docs="http://www.gnu.org/software/libc/manual/html_node/index.html"
           location="./data/glibc-2.7-2.libhover"
           name="glibc library"
           type="C">
     </library>
  </extension>

Fields are as follows:

  • id - unique id for this extension (required)
  • name - name of the extension (required)
  • library - details of the library (1 or more)
    • docs - URL location of external help documentation (optional)
    • location - location of libhover binary data (either URL or relative location to plug-in) (required)
    • name - name that will appear in the C/C++ Documentation page for this hover help (required)
    • type - one of (C, C++, or ASM) (required)

Note that the location can be specified local to the plug-in that declares the extension. This obviously saves time when accessing the data before a hover event.

Libhover Data

So what is Libhover data? Libhover data is merely a Java serialized class that is stored in binary format. Java serialization allows one to save and restore a class to/from a file. The Libhover class is really org.eclipse.linuxtools.cdt.libhover.LibhoverInfo:


 public class LibHoverInfo implements Serializable { 

 private static final long serialVersionUID = 1L; 

   public HashMap<String, ClassInfo> classes = new HashMap<String, ClassInfo>(); 
   public HashMap<String, TypedefInfo> typedefs = new HashMap<String, TypedefInfo>(); 
   public TreeMap<String, FunctionInfo> functions = new TreeMap<String, FunctionInfo>(); 

 } 


The class is just a collection of Maps from name to C++ class, name to C++ typedef, and name to C function. A C library hover info will only fill in the last map whereas a C++ library hover info will typically only fill in the first two.

C Library Data

The simplest form of Libhover data is for C functions. Looking at org.eclipse.linuxtools.cdt.libhover.FunctionInfo:


 public class FunctionInfo implements Serializable {
  
   private static final long serialVersionUID = 1L;
   private String name;
   private String prototype;
   private String desc;
   private String returnType;
   private ArrayList<String> headers;
   private ArrayList<FunctionInfo> children; 
 
 }


we see the class is made up of String fields containing the function data that will be pieced together in the hover window. The prototype is surrounded by parentheses. The desc field is treated as html format. The children field is for future support of C++ overloaded functions. This is due to the fact that we register a function by name in the HashMap to make it quickly referenced. When there is overloading of function names (C++ only), then we register the first function found in the map and then use the children field to store all others in no particular order. Currently, overloaded functions are not supported by the Libhover look-up mechanism, but this functionality could be easily added if required.

C Library Hover Utility


To aid in building C library hover data, a utility has been created that will take xml and create the libhover binary data in the form of a file with suffix ".libhover". The utility is found in the org.eclipse.linuxtools.cdt.libhover plug-in as org.eclipse.linuxtools.cdt.libhover.utils.BuildFunctionInfos.java. Run the file as a Java application (it has a static main method) and pass to it two parameters:

  1. the URL or file location of the xml file to parse
  2. the location where the output should be placed

Once finished you can place the .libhover file in your plug-in and use the Libhover Library extension to specify a local location.

XML files referenced must adhere to the following xml structure:


<!DOCTYPE descriptions [

  <!ELEMENT descriptions (construct)*>

  <!ELEMENT construct (structure|function)*>
  <!ATTLIST construct
    id ID #REQUIRED
    type CDATA #REQUIRED
  >

  <!ELEMENT structure       (synopsis?, elements?)?>

  <!ELEMENT elements     (element*)>

  <!ELEMENT element (synopsis*)>
  <!ATTLIST element
    content CDATA #REQUIRED
  >

  <!ELEMENT synopsis     (#PCDATA)*>

  <!ELEMENT function     (prototype,headers?,synopsis)>
  <!ATTLIST function
    returntype CDATA #REQUIRED
  >

  <!ELEMENT prototype    (parameter+)?>

  <!ELEMENT parameter (#PCDATA)*>
  <!ATTLIST parameter
    content CDATA #REQUIRED
  >

  <!ELEMENT headers      (header+)?>

  <!ELEMENT header (#PCDATA)*>
  <!ATTLIST header
    filename CDATA #REQUIRED
  >

]>

Note that function ids need to be prefixed by "function-". For example, for the C atexit function:

<descriptions>
  <construct id="function-atexit" type="function">
    <function returntype="int">
      <prototype>
        <parameter content="void (*function) (void)"/>
      </prototype>
      <headers>
        <header filename = "stdlib.h"/>
      </headers>
        <synopsis>
        The <CODE>atexit</CODE> function registers the function <VAR>function</VAR> to be
         called at normal program termination.  The <VAR>function</VAR> is called with
         no arguments.
         <br><br> The return value from <CODE>atexit</CODE> is zero on success and nonzero if
         the function cannot be registered.
        </synopsis>
    </function>
  </construct>
</descriptions>

Also note that the synopsis is output as html. To specify html tags, one needs to use &lt; and &gt; as delimeters in place of "&lt" and "&gt". In the previous example, VAR tags are used for variable references, CODE tags for the function name, and br tags for forcing paragraph breaks. All of these make the hover look more interesting when displayed.


For glibc, a parser was written to parse the glibc/manual directory and process the texinfo files to form the xml file format above.

C++ Library Hover

C++ library hover data is more complex. A utility org.eclipse.linuxtools.cdt.libhover.libstdcxx.DoxygenCPPInfo was created to parse the Doxygen documentation for the libstdc++ library. If you can get your library documentation into the same format, then all you need to do is to use the utility, passing two parameters:

  1. location of the Doxygen xml input
  2. location to place the output libhover data file

Failing that, you will need to create your own library hover info. Let's look at the fields of org.eclipse.linuxtools.cdt.libhover.ClassInfo

public class ClassInfo implements Serializable {

	private static final long serialVersionUID = 1L;
	private String templateParms[];
	private boolean templateParmsFilled;
	private String className;
	private String id;
	private String include;
	private ArrayList<ClassInfo> baseClasses;
	private HashMap<String, MemberInfo> members;
	private transient Document document;
	public transient Node classNode;
	private ArrayList<ClassInfo> children;
}

The following describes each field:

  • templateParms - this is used to store the template parameters of this class (e.g. A<_T, _U, Integer> would store "_T" and "_U". Real types are not part of this list. These are needed to perform replacement in the description text (e.g. the return value of a member function may be specified as a template parameter).
  • templateParmsFilled - used by DoxygenCPPInfo utility.
  • className - this is the name of the class including the template specification. Any template parameters from templateParms are replaced with a generic regex "[a-zA-Z0-9_: *]+" which allows us to do a quick regex match on a template (e.g. A<Integer, Double> would match A<_T, _U>.
  • include - this is the name of the header file that contains this class
  • baseClasses - the ClassInfo data of any base classes of this class
  • members - maps member names to MemberInfo (only 1 per name with MemberInfo chaining when overloading exists).
  • document - used by DoxygenCPPInfo utility
  • classNode - used by DoxygenCPPInfo utility
  • children - this is the set of template classes with the same name as this class

Note that the name used to hash the ClassInfo in the LibhoverInfo class map is the class name minus any template specification.

The MemberInfo class is much like the FunctionInfo class:

public class MemberInfo implements Serializable {

	private static final long serialVersionUID = 1L;
	private String name;
	private String prototype;
	private String desc;
	private String returnType;
	private String[] paramTypes;
	private ArrayList<MemberInfo> children;
	
};

and contains the actual hover data of interest. The following are the fields:

  • name - member name
  • prototype - prototype minus parentheses
  • desc - member description in html format
  • returnType - the return type of the member function
  • paramTypes - an array of just the parameter types of this function without template replacement. The array is used in conjunction with template types to verify we have the correct member being used (e.g. a(_T, _U) of A<_T, _U> is a match for a(Integer k, Double l) of A<Integer, Double> class).
  • children - members with the same name as this (i.e. overloaded method signatures)

Back to the top