Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Formatter/HTML/ScopeSorter.py
    1| # $Id: ScopeSorter.py,v 1.8 2002/10/28 06:12:31 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2000, 2001 Stephen Davies
    5| # Copyright (C) 2000, 2001 Stefan Seefeld
    6| #
    7| # Synopsis is free software; you can redistribute it and/or modify it
    8| # under the terms of the GNU General Public License as published by
    9| # the Free Software Foundation; either version 2 of the License, or
   10| # (at your option) any later version.
   11| #
   12| # This program is distributed in the hope that it will be useful,
   13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15| # General Public License for more details.
   16| #
   17| # You should have received a copy of the GNU General Public License
   18| # along with this program; if not, write to the Free Software
   19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20| # 02111-1307, USA.
   21| #
   22| # $Log: ScopeSorter.py,v $
   23| # Revision 1.8  2002/10/28 06:12:31  chalky
   24| # Add structs_as_classes option
   25| #
   26| # Revision 1.7  2001/07/15 08:28:43  chalky
   27| # Added 'Inheritance' page Part
   28| #
   29| # Revision 1.6  2001/06/26 04:32:16  stefan
   30| # A whole slew of changes mostly to fix the HTML formatter's output generation,
   31| # i.e. to make the output more robust towards changes in the layout of files.
   32| #
   33| # the rpm script now works, i.e. it generates source and binary packages.
   34| #
   35| # Revision 1.5  2001/06/11 10:37:49  chalky
   36| # Better grouping support
   37| #
   38| # Revision 1.4  2001/02/12 04:08:09  chalky
   39| # Added config options to HTML and Linker. Config demo has doxy and synopsis styles.
   40| #
   41| # Revision 1.3  2001/02/06 05:13:05  chalky
   42| # Fixes
   43| #
   44| # Revision 1.2  2001/02/01 15:23:24  chalky
   45| # Copywritten brown paper bag edition.
   46| #
   47| #
   48| 
   49| """Scope sorting class module.
   50| This module contains the class for sorting Scopes.
   51| """
   52| # System modules
   53| import string
   54| 
   55| # Synopsis modules
   56| from Synopsis.Core import AST
   57| 
   58| # HTML modules
   59| import core
   60| 
   61| # The names of the access types
   62| _axs_str = ('','Public ','Protected ','Private ')
   63| 
   64| # The predefined order for section names
   65| _section_order = (
   66|     'Namespace', 'Module', 'Class', 'Typedef', 'Struct', 'Enum', 'Union',
   67|     'Group', 'Member function', 'Function'
   68| )
   69| 
   70| # Compare two section names
   71| def compare_sections(a, b):
   72|     # Determine access of each name
   73|     ai, bi = 0, 0
   74|     an, bn = a, b
   75|     for i in range(1,4):
   76|         access = _axs_str[i]
   77|         len_access = len(access)
   78|         is_a = (a[:len_access] == access)
   79|         is_b = (b[:len_access] == access)
   80|         if is_a:
   81|             if not is_b: return -1 # a before b
   82|             # Both matched
   83|             an = a[len_access:]
   84|             bn = b[len_access:]
   85|          break
   86|         if is_b:
   87|             return 1 # b before a
   88|         # Neither matched
   89|     # Same access, sort by predefined order 
   90|     for section in _section_order:
   91|         if an == section: return -1 # a before b
   92|         if bn == section: return 1 # b before a
   93|     return 0
   94| 
   95| class ScopeSorter:
   96|     """A class that takes a scope and sorts its children by type. To use it
   97|     call set_scope, then access the sorted list by the other methods."""
   98|     def __init__(self, scope=None):
   99|         "Optional scope starts using that AST.Scope"
  100|         self.__scope = None
  101|         if scope: self.set_scope(scope)
  102|         self.__structs_as_classes = core.config.structs_as_classes
  103|     def set_scope(self, scope):
  104|         "Sort children of given scope"
  105|         if scope is self.__scope: return
  106|         self.__sections = []
  107|         self.__section_dict = {}
  108|         self.__children = []
  109|         self.__child_dict = {}
  110|         self.__scope = scope
  111|         self.__sorted_sections = 0
  112|         self.__sorted_secnames = 0
  113|         scopename = scope.name()
  114|         for decl in scope.declarations():
  115|             if isinstance(decl, AST.Forward): continue
  116|             if isinstance(decl, AST.Group) and decl.__class__.__name__ == 'Group':
  117|                self._handle_group(decl)
  118|                continue
  119|             name, section = decl.name(), self._section_of(decl)
  120|             if len(name) > 1 and name[:-1] != scopename: continue
  121|             self._add_decl(decl, name, section)
  122|         self._sort_sections()
  123|     def _add_decl(self, decl, name, section):
  124|         "Adds the given decl with given name and section to the internal data"
  125|         if not self.__section_dict.has_key(section):
  126|             self.__section_dict[section] = []
  127|             self.__sections.append(section)
  128|         self.__section_dict[section].append(decl)
  129|         self.__children.append(decl)
  130|         self.__child_dict[tuple(name)] = decl
  131|     def _section_of(self, decl):
  132|         section = string.capitalize(decl.type())
  133|         if self.__structs_as_classes and section == 'Struct':
  134|             section = 'Class'
  135|         if decl.accessibility != AST.DEFAULT:
  136|             section = _axs_str[decl.accessibility()]+section
  137|         return section
  138|     def _sort_sections(self): pass
  139|     def sort_section_names(self):
  140|         """Sorts sections names if they need it"""
  141|         if self.__sorted_secnames: return
  142|         self.__sections.sort(compare_sections)
  143|         self.__sorted_secnames = 1
  144|     def _set_section_names(self, sections): self.__sections = sections
  145|     def _handle_group(self, group):
  146|         """Handles a group"""
  147|         section = group.name()[-1]
  148|         self._add_decl(group, group.name(), section)
  149|         for decl in group.declarations():
  150|             name = decl.name()
  151|             self._add_decl(decl, name, section)
  152|     def sort_sections(self):
  153|         """Sorts the children of all sections, if they need it"""
  154|         if self.__sorted_sections: return
  155|         for children in self.__section_dict.values()+[self.__children]:
  156|             dict = {}
  157|             for child in children: dict[child.name()] = child
  158|             names = dict.keys()
  159|             core.sort(names)
  160|             del children[:]
  161|             for name in names: children.append(dict[name])
  162|         self.__sorted_sections = 1
  163|     def child(self, name):
  164|         "Returns the child with the given name. Throws KeyError if not found."
  165|         return self.__child_dict[name]
  166|     def sections(self):
  167|         "Returns a list of available section names"
  168|         return self.__sections
  169|     def children(self, section=None):
  170|         "Returns list of children in given section, or all children"
  171|         if section is None: return self.__children
  172|         if self.__section_dict.has_key(section):
  173|             return self.__section_dict[section]
  174|         return {}
  175| 
  176|