<div dir="ltr">Hi there,<div><br></div><div>I've only just starting using clang/cindex.py as a parser and I want to be able to get doxygen style comments associated with #defines in C source code. The cursor.raw_comment doesn't seem to be populated for preprocessor defines so in order to fetch doxygen style comments I've done this:</div><div><br></div><div><span style="font-family:monospace">for cursor in cursor.get_children()</span></div><span style="font-family:monospace">    if(cursor.kind == clang.cindex.CursorKind.MACRO_</span><span style="font-family:monospace">DEFINITION):</span><br><font face="monospace"><br></font><span style="font-family:monospace">        </span><font color="#6aa84f" style="font-family:monospace"># Get position of the preprocessor define</font><br><span style="font-family:monospace">        start = cursor.extent.start.offset</span><br><span style="font-family:monospace">        end   = cursor.extent.end.offset+1</span><br><span style="font-family:monospace">    </span><br><div><font face="monospace">        <font color="#6aa84f"># Get the extent from the source file. Not sure why</font></font></div><div><font face="monospace"><font color="#6aa84f">        # I need start-2 instead of start.</font></font></div><span style="font-family:monospace">        extent = tu.get_extent(path_of_source, (0, start-2)</span><br><font face="monospace"><br></font><span style="font-family:monospace">        </span><font color="#6aa84f" style="font-family:monospace"># Get the list of tokens before the pre-processor define</font><br><span style="font-family:monospace">        tokens = clang.cindex.TokenGroup.get_</span><span style="font-family:monospace">tokens(tu, extent)</span><br><font face="monospace"><br></font><span style="font-family:monospace">        </span><font color="#6aa84f" style="font-family:monospace"># Reverse the generator so that we can walk backwards through</font><br><span style="color:rgb(106,168,79);font-family:monospace">        # the token list to extract comments before the preprocessor</span><br><span style="color:rgb(106,168,79);font-family:monospace">        # definition. This is painfully slow.</span><br><span style="font-family:monospace">        tokens = reversed(list(tokens))</span><br><div><font face="monospace"><br></font></div><span style="font-family:monospace">        comment = None</span><br><div><font face="monospace"><br></font></div><div><font face="monospace">        for t in tokens:</font></div><div><font face="monospace">            if(t.spelling in ('#', 'define')):</font></div><div><font face="monospace">                continue</font></div><div><font face="monospace">            elif(t.kind == clang.cindex.TokenKind.COMMENT):</font></div><div><font face="monospace">                comment = t.spelling</font></div><span style="font-family:monospace">            break</span><div><font face="monospace">            </font></div><div><div><font face="monospace">        if(comment != None and comment.startswith('/**')):</font></div><div><font face="monospace">            <font color="#6aa84f"># process comment for this preprocessor statement    </font></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><br></blockquote>I'd like to get the token list in reverse order so that I can walk backwards looking for comments associated with the #define. That has a lot of overhead in Python if the token list is large so I've added a method called get_rtokens() to the TokenGroup class which returns the tokens in the reverse order:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><font face="monospace">class TokenGroup(object):</font></div><div><font face="monospace">    ...</font></div><div><div><font face="monospace">    @staticmethod</font></div></div><div><div><font face="monospace">    def <b>get_rtokens</b>(tu, extent):</font></div></div><div><div><font face="monospace">        <font color="#38761d">"""Helper method to return all tokens in an extent in reverse order</font></font></div></div><div><div><font face="monospace" color="#38761d">           to avoid the expense of having to convert the returned generator</font></div></div><div><div><font face="monospace" color="#38761d">           to a list and then calling reverse() on it.</font></div></div><div><div><font face="monospace" color="#38761d">        """</font></div></div><div><div><font face="monospace">        tokens_memory = POINTER(Token)()</font></div></div><div><div><font face="monospace">        tokens_count = c_uint()</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        conf.lib.clang_tokenize(tu, extent, byref(tokens_memory),</font></div></div><div><div><font face="monospace">                byref(tokens_count))</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        count = int(tokens_count.value)</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        <font color="#6aa84f"># If we get no tokens, no memory was allocated. Be sure not to return</font></font></div></div><div><div><font face="monospace" color="#6aa84f">        # anything and potentially call a destructor on nothing.</font></div></div><div><div><font face="monospace">        if count < 1:</font></div></div><div><div><font face="monospace">            return</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        tokens_array = cast(tokens_memory, POINTER(Token * count)).contents</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        token_group = TokenGroup(tu, tokens_memory, tokens_count)</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">        for i in xrange(count-1, 0, -1):</font></div></div><div><div><font face="monospace">            token = Token()</font></div></div><div><div><font face="monospace">            token.int_data = tokens_array[i].int_data</font></div></div><div><div><font face="monospace">            token.ptr_data = tokens_array[i].ptr_data</font></div></div><div><div><font face="monospace">            token._tu = tu</font></div></div><div><div><font face="monospace">            token._group = token_group</font></div></div><div><div><font face="monospace"><br></font></div></div><div><div><font face="monospace">            yield token</font></div></div></blockquote><div><div><br></div><div>I'm wondering if anyone has accomplished this in a better way or whether the the get_rtokens() method would be useful to other people. What I really want to do is relate a cursor to a token and then navigate forward and backwards from that token but I can't see how to do that.</div><div><br></div><div><div>Thanks,</div><div><br></div><div>Brad Elliott</div></div></div></div></div>