Changeset f767355d in rtems


Ignore:
Timestamp:
May 1, 2020, 7:52:42 AM (6 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
5, master
Children:
285cda3
Parents:
a8f0d94
git-author:
Chris Johns <chrisj@…> (05/01/20 07:52:42)
git-committer:
Chris Johns <chrisj@…> (05/01/20 08:03:49)
Message:

rtems-bsps: Add markdown support

  • Convert to python for better performance
File:
1 edited

Legend:

Unmodified
Added
Removed
  • rtems-bsps

    ra8f0d94 rf767355d  
    1 #! /bin/sh
    2 
    3 top=$(dirname $0)
    4 base="${top}/bsps"
    5 base_e=$(echo ${base} | sed -e 's/\//\\\//g')
    6 
    7 last_arch=""
    8 
    9 cfg_list=$(LANG=C LC_COLLATE=C find ${base} -mindepth 3 -name \*.cfg | sort)
    10 
    11 max_bsp_len=0
    12 arch_count=0
    13 bsp_count=0
    14 
    15 for bsp_path in ${cfg_list};
    16 do
    17   arch=$(echo ${bsp_path} | sed -e "s/${base_e}*\///" -e 's/\/.*//')
    18   bsp=$(echo ${bsp_path} | sed -e "s/.*\///" -e 's/\.cfg//')
    19   len=${#bsp}
    20   if test "${last_arch}" != "${arch}"; then
    21     arch_count=$(expr ${arch_count} + 1)
    22     last_arch=${arch}
    23   fi
    24   if [ $len -gt $max_bsp_len ]; then
    25     max_bsp_len=$len
    26   fi
    27   bsp_count=$(expr ${bsp_count} + 1)
    28 done
    29 
    30 max_bsp_len=$(expr ${max_bsp_len} + 2)
    31 last_arch=""
    32 
    33 echo "RTEMS 5"
    34 echo " Architectures: ${arch_count}"
    35 echo " BSP Count: ${bsp_count}"
    36 for bsp_path in ${cfg_list};
    37 do
    38  arch=$(echo ${bsp_path} | sed -e "s/${base_e}*\///" -e 's/\/.*//')
    39  bsp=$(echo ${bsp_path} | sed -e "s/.*\///" -e 's/\.cfg//')
    40  path=$(echo ${bsp_path} | sed -e "s/\/config.*//")
    41  if test "${last_arch}" != "${arch}"; then
    42    echo "${arch}:"
    43    last_arch=${arch}
    44  fi
    45  spaces=$(echo ${bsp} | awk '{ printf("%*s", '${max_bsp_len}' -length(), " "); }')
    46  echo " ${bsp}${spaces}${path}"
    47 done
    48 
    49 exit 0
     1#! /usr/bin/env python
     2#
     3# RTEMS (http://www.rtems.org/)
     4# Copyright 2020 Chris Johns (chrisj@rtems.org)
     5# All rights reserved.
     6#
     7# Redistribution and use in source and binary forms, with or without
     8# modification, are permitted provided that the following conditions are met:
     9#
     10# 1. Redistributions of source code must retain the above copyright notice,
     11# this list of conditions and the following disclaimer.
     12#
     13# 2. Redistributions in binary form must reproduce the above copyright notice,
     14# this list of conditions and the following disclaimer in the documentation
     15# and/or other materials provided with the distribution.
     16#
     17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27# POSSIBILITY OF SUCH DAMAGE.
     28#
     29
     30from __future__ import print_function
     31
     32import argparse
     33import os
     34import os.path
     35import sys
     36
     37rtems_version = 5
     38
     39
     40class ArchBsps:
     41    """Collects and processes the BSPs for a range of architectures
     42    creating output in text, markdown and HTML ir pandoc is installed"""
     43    def __init__(self, path='.', trace=False):
     44        self.trace = trace
     45        self._output = []
     46        self.top = os.path.realpath(path)
     47        self.base = os.path.join(self.top, 'bsps')
     48        self.configs = []
     49        self.archs = {}
     50        self._collect('.cfg')
     51        self._process()
     52
     53    def _clear(self):
     54        """Clears the output."""
     55        self._output = []
     56
     57    def _out(self, line=''):
     58        """Output a line to the output buffer."""
     59        self._output += [line]
     60
     61    def _collect(self, ext):
     62        """Collect the config files from the source tree."""
     63        self.configs = []
     64        for root, dirs, files in os.walk(self.base, topdown=True):
     65            for f in files:
     66                if os.path.splitext(f)[1] == ext:
     67                    self.configs += [os.path.join(root, f)]
     68
     69    def _process(self):
     70        """Process the collected list of config files."""
     71        self.archs = {}
     72        for cfg in self.configs:
     73            config_path = cfg[len(self.base) + 1:]
     74            config_parts = config_path.split(os.sep)
     75            if len(config_parts) == 4:
     76                arch = config_parts[0]
     77                family = config_parts[1]
     78                bsp = os.path.splitext(config_parts[3])[0]
     79                if arch not in self.archs:
     80                    self.archs[arch] = {}
     81                if family not in self.archs[arch]:
     82                    self.archs[arch][family] = {}
     83                self.archs[arch][family][bsp] = config_path
     84
     85    def _max_arch_len(self):
     86        """Finds the longest arch label"""
     87        maxlen = 0
     88        for arch in self.archs:
     89            if len(arch) > maxlen:
     90                maxlen = len(arch)
     91        return maxlen
     92
     93    def _max_family_len(self):
     94        """Finds the longest family label"""
     95        maxlen = 0
     96        for arch in self.archs:
     97            for family in self.archs[arch]:
     98                if len(family) > maxlen:
     99                    maxlen = len(family)
     100        return maxlen
     101
     102    def _max_bsp_len(self):
     103        """Finds the longest BSP label"""
     104        maxlen = 0
     105        for arch in self.archs:
     106            for family in self.archs[arch]:
     107                for bsp in self.archs[arch][family]:
     108                    if len(bsp) > maxlen:
     109                        maxlen = len(bsp)
     110        return maxlen
     111
     112    def _max_bsp_path_len(self):
     113        """Finds the longest BSP path"""
     114        maxlen = 0
     115        for arch in self.archs:
     116            for family in self.archs[arch]:
     117                for bsp in self.archs[arch][family]:
     118                    if len(self.archs[arch][family][bsp]) > maxlen:
     119                        maxlen = len(self.archs[arch][family][bsp])
     120        return maxlen
     121
     122    def title(self):
     123        """Returns the output's title"""
     124        return 'RTEMS %d Board Support Packages' % (rtems_version)
     125
     126    def output(self):
     127        """Return the output"""
     128        return self._output
     129
     130    def architectures(self):
     131        """Returns the number of architectures we have"""
     132        return len(self.archs)
     133
     134    def families(self, arch=None):
     135        """Returns the number of BSP families we have for an architecture. If
     136        you supply an architecture the count is the families in the
     137        architure.
     138
     139        """
     140        if arch is not None:
     141            return len(self.archs[arch])
     142        count = 0
     143        for arch in self.archs:
     144            count += len(self.archs[arch])
     145        return count
     146
     147    def bsps(self, arch=None, family=None):
     148        """Returns the number of BSPs we have for an architecture or a family"""
     149        count = 0
     150        if arch is not None and family is not None:
     151            count = len(self.archs[arch][family])
     152        elif arch is None and family is not None:
     153            for arch in self.archs:
     154                if family in self.archs[arch]:
     155                    count = len(self.archs[arch][family])
     156                    break
     157        elif arch is not None and family is None:
     158            count = 0
     159            for family in self.archs[arch]:
     160                count += len(self.archs[arch][family])
     161        else:
     162            for arch in self.archs:
     163                for family in self.archs[arch]:
     164                    count += len(self.archs[arch][family])
     165        return count
     166
     167    def text(self, arch_selector=None, family_selector=None, show_path=False):
     168        """Generate plain text output"""
     169        self._clear()
     170        self._out(self.title())
     171        self._out()
     172        self._out('Architectures: %d' % (self.architectures()))
     173        self._out('BSP Families: %d' % (self.families()))
     174        self._out('BSPs: %d' % (self.bsps()))
     175        max_family = self._max_family_len()
     176        max_bsp = self._max_bsp_len()
     177        if arch_selector is None:
     178            archs_matcher = []
     179        else:
     180            archs_matcher = [a.strip() for a in arch_selector.split(',')]
     181        if family_selector is None:
     182            family_matcher = []
     183        else:
     184            family_matcher = [f.strip() for f in family_selector.split(',')]
     185        for arch in sorted(self.archs.keys()):
     186            if arch_selector is None or arch in archs_matcher:
     187                first = True
     188                for family in sorted(self.archs[arch].keys()):
     189                    if family_selector is None or family in family_matcher:
     190                        if first:
     191                            self._out()
     192                            self._out('%s: (families:%d bsps:%d)' % \
     193                                      (arch,
     194                                       self.families(arch=arch),
     195                                       self.bsps(arch=arch)))
     196                            first = False
     197                        for bsp in sorted(self.archs[arch][family].keys()):
     198                            if show_path:
     199                                p = os.path.join('bsps',
     200                                                 self.archs[arch][family][bsp])
     201                                self._out(' %-*s %-*s %s' % \
     202                                          (max_bsp, bsp, max_family, family, p))
     203                            else:
     204                                self._out(' %-*s %s' % (max_bsp, bsp, family))
     205
     206    def markdown(self,
     207                 arch_selector=None,
     208                 family_selector=None,
     209                 show_path=False,
     210                 show_title=False):
     211        """Generates markdown output"""
     212        self._clear()
     213        if show_title:
     214            self._out('# ' + self.title())
     215            self._out()
     216        self._out('**Architectures:** %d  ' % (self.architectures()))
     217        self._out('**BSP Families:** %d  ' % (self.families()))
     218        self._out('**BSPs:** %d  ' % (self.bsps()))
     219        max_arch = self._max_arch_len()
     220        max_family = self._max_family_len()
     221        max_bsp = self._max_bsp_len()
     222        max_bsp_path = self._max_bsp_path_len() + 4
     223        if arch_selector is None:
     224            archs_matcher = []
     225        else:
     226            archs_matcher = [a.strip() for a in arch_selector.split(',')]
     227        if family_selector is None:
     228            family_matcher = []
     229        else:
     230            family_matcher = [f.strip() for f in family_selector.split(',')]
     231        for arch in sorted(self.archs.keys()):
     232            if arch_selector is None or arch in archs_matcher:
     233                first = True
     234                for family in sorted(self.archs[arch].keys()):
     235                    if family_selector is None or family in family_matcher:
     236                        if first:
     237                            fbs = 'families:%-2d bsps:%-3d' % \
     238                                (self.families(arch=arch),
     239                                 self.bsps(arch=arch))
     240                            if max_family < len(fbs):
     241                                max_fb = len(fbs)
     242                            else:
     243                                max_fb = max_family
     244                            self._out()
     245                            if show_path:
     246                                self._out('%-*s |%-*s |' %
     247                                          (max_bsp, arch, max_fb, fbs))
     248                                self._out('%s-|%s-|-%s' %
     249                                          ('-' * max_bsp, '-' * max_fb,
     250                                           '-' * max_bsp_path))
     251                            else:
     252                                self._out('%-*s |%s' % (max_bsp, arch, fbs))
     253                                self._out('%s-|-%s' %
     254                                          ('-' * max_bsp, '-' * max_fb))
     255                            first = False
     256                        for bsp in sorted(self.archs[arch][family].keys()):
     257                            if show_path:
     258                                p = os.path.join('bsps',
     259                                                 self.archs[arch][family][bsp])
     260                                self._out('%-*s |%-*s |%s' % \
     261                                          (max_bsp, bsp, max_fb, family, p))
     262                            else:
     263                                self._out('%-*s |%s' % (max_bsp, bsp, family))
     264
     265
     266def run(args):
     267    """Runs the command"""
     268    argsp = argparse.ArgumentParser(
     269        prog='rtems-bsps',
     270        description='List the BSP and architectures in RTEMS')
     271    argsp.add_argument('-a',
     272                       '--arch',
     273                       help='Output the BSPs in an architecture',
     274                       type=str,
     275                       default=None)
     276    argsp.add_argument('-f',
     277                       '--family',
     278                       help='Output the BSPs in an architecture family',
     279                       type=str,
     280                       default=None)
     281    argsp.add_argument('-p',
     282                       '--paths',
     283                       help='Show the BSP paths in the output',
     284                       action='store_true')
     285    argsp.add_argument('-m',
     286                       '--markdown',
     287                       help='Output list in markdown format',
     288                       action='store_true')
     289    argsp.add_argument('-T',
     290                       '--title',
     291                       help='Output a title in the markdown format',
     292                       action='store_true')
     293    argsp.add_argument('-v',
     294                       '--trace',
     295                       help='Verbose or trace for debugging',
     296                       action='store_true')
     297
     298    argopts = argsp.parse_args(args[1:])
     299
     300    if argopts.arch is not None and argopts.family is not None:
     301        print('error: arch or family, not both at once', file=sys.stderr)
     302        sys.exit(1)
     303
     304    ab = ArchBsps(trace=argopts.trace)
     305
     306    if argopts.markdown:
     307        ab.markdown(arch_selector=argopts.arch,
     308                    family_selector=argopts.family,
     309                    show_path=argopts.paths,
     310                    show_title=argopts.title)
     311    else:
     312        ab.text(arch_selector=argopts.arch,
     313                family_selector=argopts.family,
     314                show_path=argopts.paths)
     315
     316    print(os.linesep.join(ab.output()))
     317
     318
     319if __name__ == "__main__":
     320    run(sys.argv)
Note: See TracChangeset for help on using the changeset viewer.