1# 2# Copyright 2010 Free Software Foundation, Inc. 3# 4# This file is part of GNU Radio 5# 6# GNU Radio is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3, or (at your option) 9# any later version. 10# 11# GNU Radio is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with GNU Radio; see the file COPYING. If not, write to 18# the Free Software Foundation, Inc., 51 Franklin Street, 19# Boston, MA 02110-1301, USA. 20# 21""" 22Classes providing more user-friendly interfaces to the doxygen xml 23docs than the generated classes provide. 24""" 25 26import os 27 28from generated import index 29from base import Base 30from text import description 31 32class DoxyIndex(Base): 33 """ 34 Parses a doxygen xml directory. 35 """ 36 37 __module__ = "gnuradio.utils.doxyxml" 38 39 def _parse(self): 40 if self._parsed: 41 return 42 super(DoxyIndex, self)._parse() 43 self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) 44 for mem in self._root.compound: 45 converted = self.convert_mem(mem) 46 # For files and namespaces we want the contents to be 47 # accessible directly from the parent rather than having 48 # to go through the file object. 49 if self.get_cls(mem) == DoxyFile: 50 if mem.name.endswith('.h'): 51 self._members += converted.members() 52 self._members.append(converted) 53 elif self.get_cls(mem) == DoxyNamespace: 54 self._members += converted.members() 55 self._members.append(converted) 56 else: 57 self._members.append(converted) 58 59 60def generate_swig_doc_i(self): 61 """ 62 %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " 63 Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; 64 """ 65 pass 66 67 68class DoxyCompMem(Base): 69 70 71 kind = None 72 73 def __init__(self, *args, **kwargs): 74 super(DoxyCompMem, self).__init__(*args, **kwargs) 75 76 @classmethod 77 def can_parse(cls, obj): 78 return obj.kind == cls.kind 79 80 def set_descriptions(self, parse_data): 81 bd = description(getattr(parse_data, 'briefdescription', None)) 82 dd = description(getattr(parse_data, 'detaileddescription', None)) 83 self._data['brief_description'] = bd 84 self._data['detailed_description'] = dd 85 86 def set_parameters(self, data): 87 vs = [ddc.value for ddc in data.detaileddescription.content_] 88 pls = [] 89 for v in vs: 90 if hasattr(v, 'parameterlist'): 91 pls += v.parameterlist 92 pis = [] 93 for pl in pls: 94 pis += pl.parameteritem 95 dpis = [] 96 for pi in pis: 97 dpi = DoxyParameterItem(pi) 98 dpi._parse() 99 dpis.append(dpi) 100 self._data['params'] = dpis 101 102 103class DoxyCompound(DoxyCompMem): 104 pass 105 106class DoxyMember(DoxyCompMem): 107 pass 108 109class DoxyFunction(DoxyMember): 110 111 __module__ = "gnuradio.utils.doxyxml" 112 113 kind = 'function' 114 115 def _parse(self): 116 if self._parsed: 117 return 118 super(DoxyFunction, self)._parse() 119 self.set_descriptions(self._parse_data) 120 self.set_parameters(self._parse_data) 121 if not self._data['params']: 122 # If the params weren't set by a comment then just grab the names. 123 self._data['params'] = [] 124 prms = self._parse_data.param 125 for prm in prms: 126 self._data['params'].append(DoxyParam(prm)) 127 128 brief_description = property(lambda self: self.data()['brief_description']) 129 detailed_description = property(lambda self: self.data()['detailed_description']) 130 params = property(lambda self: self.data()['params']) 131 132Base.mem_classes.append(DoxyFunction) 133 134 135class DoxyParam(DoxyMember): 136 137 __module__ = "gnuradio.utils.doxyxml" 138 139 def _parse(self): 140 if self._parsed: 141 return 142 super(DoxyParam, self)._parse() 143 self.set_descriptions(self._parse_data) 144 self._data['declname'] = self._parse_data.declname 145 146 @property 147 def description(self): 148 descriptions = [] 149 if self.brief_description: 150 descriptions.append(self.brief_description) 151 if self.detailed_description: 152 descriptions.append(self.detailed_description) 153 return '\n\n'.join(descriptions) 154 155 brief_description = property(lambda self: self.data()['brief_description']) 156 detailed_description = property(lambda self: self.data()['detailed_description']) 157 name = property(lambda self: self.data()['declname']) 158 159class DoxyParameterItem(DoxyMember): 160 """A different representation of a parameter in Doxygen.""" 161 162 def _parse(self): 163 if self._parsed: 164 return 165 super(DoxyParameterItem, self)._parse() 166 names = [] 167 for nl in self._parse_data.parameternamelist: 168 for pn in nl.parametername: 169 names.append(description(pn)) 170 # Just take first name 171 self._data['name'] = names[0] 172 # Get description 173 pd = description(self._parse_data.get_parameterdescription()) 174 self._data['description'] = pd 175 176 description = property(lambda self: self.data()['description']) 177 name = property(lambda self: self.data()['name']) 178 179 180class DoxyClass(DoxyCompound): 181 182 __module__ = "gnuradio.utils.doxyxml" 183 184 kind = 'class' 185 186 def _parse(self): 187 if self._parsed: 188 return 189 super(DoxyClass, self)._parse() 190 self.retrieve_data() 191 if self._error: 192 return 193 self.set_descriptions(self._retrieved_data.compounddef) 194 self.set_parameters(self._retrieved_data.compounddef) 195 # Sectiondef.kind tells about whether private or public. 196 # We just ignore this for now. 197 self.process_memberdefs() 198 199 brief_description = property(lambda self: self.data()['brief_description']) 200 detailed_description = property(lambda self: self.data()['detailed_description']) 201 params = property(lambda self: self.data()['params']) 202 203Base.mem_classes.append(DoxyClass) 204 205 206class DoxyFile(DoxyCompound): 207 208 __module__ = "gnuradio.utils.doxyxml" 209 210 kind = 'file' 211 212 def _parse(self): 213 if self._parsed: 214 return 215 super(DoxyFile, self)._parse() 216 self.retrieve_data() 217 self.set_descriptions(self._retrieved_data.compounddef) 218 if self._error: 219 return 220 self.process_memberdefs() 221 222 brief_description = property(lambda self: self.data()['brief_description']) 223 detailed_description = property(lambda self: self.data()['detailed_description']) 224 225Base.mem_classes.append(DoxyFile) 226 227 228class DoxyNamespace(DoxyCompound): 229 230 __module__ = "gnuradio.utils.doxyxml" 231 232 kind = 'namespace' 233 234 def _parse(self): 235 if self._parsed: 236 return 237 super(DoxyNamespace, self)._parse() 238 self.retrieve_data() 239 self.set_descriptions(self._retrieved_data.compounddef) 240 if self._error: 241 return 242 self.process_memberdefs() 243 244Base.mem_classes.append(DoxyNamespace) 245 246 247class DoxyGroup(DoxyCompound): 248 249 __module__ = "gnuradio.utils.doxyxml" 250 251 kind = 'group' 252 253 def _parse(self): 254 if self._parsed: 255 return 256 super(DoxyGroup, self)._parse() 257 self.retrieve_data() 258 if self._error: 259 return 260 cdef = self._retrieved_data.compounddef 261 self._data['title'] = description(cdef.title) 262 # Process inner groups 263 grps = cdef.innergroup 264 for grp in grps: 265 converted = DoxyGroup.from_refid(grp.refid, top=self.top) 266 self._members.append(converted) 267 # Process inner classes 268 klasses = cdef.innerclass 269 for kls in klasses: 270 converted = DoxyClass.from_refid(kls.refid, top=self.top) 271 self._members.append(converted) 272 # Process normal members 273 self.process_memberdefs() 274 275 title = property(lambda self: self.data()['title']) 276 277 278Base.mem_classes.append(DoxyGroup) 279 280 281class DoxyFriend(DoxyMember): 282 283 __module__ = "gnuradio.utils.doxyxml" 284 285 kind = 'friend' 286 287Base.mem_classes.append(DoxyFriend) 288 289 290class DoxyOther(Base): 291 292 __module__ = "gnuradio.utils.doxyxml" 293 294 kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 295 'dir', 'page', 'signal', 'slot', 'property']) 296 297 @classmethod 298 def can_parse(cls, obj): 299 return obj.kind in cls.kinds 300 301Base.mem_classes.append(DoxyOther) 302