* [Buildroot] [PATCH 01/11 RFC] support/scripts: prepare expanding the packages lists
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-29 20:38 ` [Buildroot] [PATCH 02/11 RFC] support/scripts: document args to _is_package() in gen-manual-lists Yann E. MORIN
` (10 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Move the code generating the package name from a symbol to a function,
to avoid code duplication.
This is not used currently, but will be in a subsequent patch.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index 94f403e..aee2299 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -245,7 +245,7 @@ class Buildroot:
"""
if not self.re_pkg_prefix.match(symbol.get_name()):
return False
- pkg_name = re.sub("BR2_PACKAGE_(HOST_)?(.*)", r"\2", symbol.get_name())
+ pkg_name = self._get_pkg_name(symbol)
pattern = "^(HOST_)?" + pkg_name + "$"
pattern = re.sub("_", ".", pattern)
@@ -278,6 +278,15 @@ class Buildroot:
return True
return False
+ def _get_pkg_name(self, symbol):
+ """ Return the package name of the specified symbol.
+
+ :param symbol: The symbol to get the package name of
+
+ """
+
+ return re.sub("BR2_PACKAGE_(HOST_)?(.*)", r"\2", symbol.get_name())
+
def _get_symbol_label(self, symbol, mark_deprecated=True):
""" Return the label (a.k.a. prompt text) of the symbol.
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 02/11 RFC] support/scripts: document args to _is_package() in gen-manual-lists
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
2014-05-29 20:38 ` [Buildroot] [PATCH 01/11 RFC] support/scripts: prepare expanding the packages lists Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:18 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists Yann E. MORIN
` (9 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index aee2299..b33fcf0 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -242,6 +242,8 @@ class Buildroot:
""" Return True if the symbol is a package or a host package, otherwise
False.
+ :param symbol: The symbol to check
+
"""
if not self.re_pkg_prefix.match(symbol.get_name()):
return False
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
2014-05-29 20:38 ` [Buildroot] [PATCH 01/11 RFC] support/scripts: prepare expanding the packages lists Yann E. MORIN
2014-05-29 20:38 ` [Buildroot] [PATCH 02/11 RFC] support/scripts: document args to _is_package() in gen-manual-lists Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:19 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display " Yann E. MORIN
` (8 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Prepare to tell apart real packages from virtual packages.
Currently, the code implicitly recognises only real packages, and
discards virtual package, because of the heuristic used to recognise
whether a symbol is a package:
- for real package:
- symbols : BR2_PACKAGE_FOO
- .mk files: foo.mk
- for virtual packages:
- symbols : BR2_PACKAGE_HAS_FOO
- .mk files: foo.mk
The current heuristic is to check for each symbol if a corresponding .mk
file exist, by stripping 'BR2_PACAKGE_' from the beginning of the symbol
converting the result to lowercase, and checking of a .mk file exists.
So, as a side effect, it completely misses the virtual packages [*], which
is pretty nice since we get a list with only reall packages that the user
can indeed select and see in the menuconfig.
[*] Except for 'jpeg' which is both a virtual package and a normal package.
Except it is not a normal package, it is used to enable either libjpeg or
jpegturbo. This case will be fixed in a follow-up patch.
Since we'll soon need to also output the table of virtual packages, we
need to teach the _is_package() function to recongise them as well.
This patch is the first step into that direction: it introduces a new
function _is_real_package() that is just a wrapper to is_package(), which
gains a new parameter, being the type of packages to filter on.
No behavioural change is made in this patch, it is just a preparatory
patch.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index b33fcf0..8dec089 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -183,14 +183,14 @@ class Buildroot:
'target-packages': {
'filename': "package-list",
'root_menu': "Target packages",
- 'filter': "_is_package",
+ 'filter': "_is_real_package",
'sorted': True,
'sub_menu': True,
},
'host-packages': {
'filename': "host-package-list",
'root_menu': "Host utilities",
- 'filter': "_is_package",
+ 'filter': "_is_real_package",
'sorted': True,
'sub_menu': False,
},
@@ -238,11 +238,13 @@ class Buildroot:
return bool([ symbol for x in symbol.get_referenced_symbols()
if x.get_name().startswith(self._deprecated.get_name()) ])
- def _is_package(self, symbol):
+ def _is_package(self, symbol, type = 'real'):
""" Return True if the symbol is a package or a host package, otherwise
False.
:param symbol: The symbol to check
+ :param type: Limit to 'real', 'virtual' or 'both' types of packages
+ Note: only 'real' is (implictly) handled for now
"""
if not self.re_pkg_prefix.match(symbol.get_name()):
@@ -280,6 +282,9 @@ class Buildroot:
return True
return False
+ def _is_real_package(self, symbol):
+ return self._is_package(symbol, 'real')
+
def _get_pkg_name(self, symbol):
""" Return the package name of the specified symbol.
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists
2014-05-29 20:38 ` [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists Yann E. MORIN
@ 2014-05-31 21:19 ` Samuel Martin
2014-05-31 22:37 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:19 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Prepare to tell apart real packages from virtual packages.
>
> Currently, the code implicitly recognises only real packages, and
> discards virtual package, because of the heuristic used to recognise
> whether a symbol is a package:
>
> - for real package:
> - symbols : BR2_PACKAGE_FOO
> - .mk files: foo.mk
> - for virtual packages:
> - symbols : BR2_PACKAGE_HAS_FOO
> - .mk files: foo.mk
>
> The current heuristic is to check for each symbol if a corresponding .mk
> file exist, by stripping 'BR2_PACAKGE_' from the beginning of the symbol
> converting the result to lowercase, and checking of a .mk file exists.
>
> So, as a side effect, it completely misses the virtual packages [*], which
> is pretty nice since we get a list with only reall packages that the user
s/reall/real/
> can indeed select and see in the menuconfig.
>
> [*] Except for 'jpeg' which is both a virtual package and a normal package.
and cryptodev ;-)
> Except it is not a normal package, it is used to enable either libjpeg or
> jpegturbo. This case will be fixed in a follow-up patch.
>
> Since we'll soon need to also output the table of virtual packages, we
> need to teach the _is_package() function to recongise them as well.
s/recongise/recongize/
>
> This patch is the first step into that direction: it introduces a new
> function _is_real_package() that is just a wrapper to is_package(), which
s/ is_package()/ _is_package()/
> gains a new parameter, being the type of packages to filter on.
>
> No behavioural change is made in this patch, it is just a preparatory
> patch.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
> ---
> support/scripts/gen-manual-lists.py | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> index b33fcf0..8dec089 100644
> --- a/support/scripts/gen-manual-lists.py
> +++ b/support/scripts/gen-manual-lists.py
> @@ -183,14 +183,14 @@ class Buildroot:
> 'target-packages': {
> 'filename': "package-list",
> 'root_menu': "Target packages",
> - 'filter': "_is_package",
> + 'filter': "_is_real_package",
> 'sorted': True,
> 'sub_menu': True,
> },
> 'host-packages': {
> 'filename': "host-package-list",
> 'root_menu': "Host utilities",
> - 'filter': "_is_package",
> + 'filter': "_is_real_package",
> 'sorted': True,
> 'sub_menu': False,
> },
> @@ -238,11 +238,13 @@ class Buildroot:
> return bool([ symbol for x in symbol.get_referenced_symbols()
> if x.get_name().startswith(self._deprecated.get_name()) ])
>
> - def _is_package(self, symbol):
> + def _is_package(self, symbol, type = 'real'):
> """ Return True if the symbol is a package or a host package, otherwise
> False.
>
> :param symbol: The symbol to check
> + :param type: Limit to 'real', 'virtual' or 'both' types of packages
> + Note: only 'real' is (implictly) handled for now
also, the default value for the type parameter is 'real'.
>
> """
> if not self.re_pkg_prefix.match(symbol.get_name()):
> @@ -280,6 +282,9 @@ class Buildroot:
> return True
> return False
>
> + def _is_real_package(self, symbol):
> + return self._is_package(symbol, 'real')
> +
> def _get_pkg_name(self, symbol):
> """ Return the package name of the specified symbol.
>
> --
> 1.8.3.2
>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists
2014-05-31 21:19 ` Samuel Martin
@ 2014-05-31 22:37 ` Yann E. MORIN
0 siblings, 0 replies; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:37 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:19 +0200, Samuel Martin spake thusly:
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
[--SNIP commit log--]
Typoes fixed.
> > diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> > index b33fcf0..8dec089 100644
> > --- a/support/scripts/gen-manual-lists.py
> > +++ b/support/scripts/gen-manual-lists.py
[--SNIP--]
> > @@ -238,11 +238,13 @@ class Buildroot:
> > return bool([ symbol for x in symbol.get_referenced_symbols()
> > if x.get_name().startswith(self._deprecated.get_name()) ])
> >
> > - def _is_package(self, symbol):
> > + def _is_package(self, symbol, type = 'real'):
> > """ Return True if the symbol is a package or a host package, otherwise
> > False.
> >
> > :param symbol: The symbol to check
> > + :param type: Limit to 'real', 'virtual' or 'both' types of packages
> > + Note: only 'real' is (implictly) handled for now
>
> also, the default value for the type parameter is 'real'.
Added.
I also removed 'both', as it's indeed never used.
Thanks!
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display virtual packages in generated lists
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (2 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 03/11 RFC] support/scripts: prepare handling virtual packages in generated lists Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:19 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package Yann E. MORIN
` (7 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
If a package has both a 'real' and a 'virtual' definition, consider it
is a virtual package and do not display it in the generated package list.
This is the case for jpeg and cryptodev, that are virtual packages, but
also real (but empty) packages used to provide a prompt to enable/disable
a choice to select an implementation. In this case, we do not want to
list the virtul packages, but only its implementations.
So, consider packages that are both real and virtual as virtual packages.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index 8dec089..10dbbd3 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -278,13 +278,30 @@ class Buildroot:
pkg_list.append(re.sub(r"(.*?)\.mk", r"\1", file_))
setattr(self, "_package_list", pkg_list)
for pkg in getattr(self, "_package_list"):
- if pattern.match(pkg):
- return True
+ if type == 'real' or type == 'both':
+ if pattern.match(pkg) and not self._exists_virt_symbol(pkg):
+ return True
return False
def _is_real_package(self, symbol):
return self._is_package(symbol, 'real')
+ def _exists_virt_symbol(self, pkg_name):
+ """ Return True if a symbol exists that defines the package as
+ a virtual package, False otherwise
+
+ :param pkg_name: The name of the package, for which to check if
+ a symbol exists defining it as a virtual package
+
+ """
+ virt_pattern = "BR2_PACKAGE_HAS_" + pkg_name + "$"
+ virt_pattern = re.sub("_", ".", virt_pattern)
+ virt_pattern = re.compile(virt_pattern, re.IGNORECASE)
+ for sym in self.config:
+ if virt_pattern.match(sym.get_name()):
+ return True
+ return False
+
def _get_pkg_name(self, symbol):
""" Return the package name of the specified symbol.
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display virtual packages in generated lists
2014-05-29 20:38 ` [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display " Yann E. MORIN
@ 2014-05-31 21:19 ` Samuel Martin
2014-05-31 22:38 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:19 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> If a package has both a 'real' and a 'virtual' definition, consider it
> is a virtual package and do not display it in the generated package list.
>
> This is the case for jpeg and cryptodev, that are virtual packages, but
> also real (but empty) packages used to provide a prompt to enable/disable
> a choice to select an implementation. In this case, we do not want to
> list the virtul packages, but only its implementations.
s/virtul/virtual/
s/its implementations/their implementations/
>
> So, consider packages that are both real and virtual as virtual packages.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
> ---
> support/scripts/gen-manual-lists.py | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> index 8dec089..10dbbd3 100644
> --- a/support/scripts/gen-manual-lists.py
> +++ b/support/scripts/gen-manual-lists.py
> @@ -278,13 +278,30 @@ class Buildroot:
> pkg_list.append(re.sub(r"(.*?)\.mk", r"\1", file_))
> setattr(self, "_package_list", pkg_list)
> for pkg in getattr(self, "_package_list"):
> - if pattern.match(pkg):
> - return True
> + if type == 'real' or type == 'both':
> + if pattern.match(pkg) and not self._exists_virt_symbol(pkg):
> + return True
> return False
>
> def _is_real_package(self, symbol):
> return self._is_package(symbol, 'real')
>
> + def _exists_virt_symbol(self, pkg_name):
> + """ Return True if a symbol exists that defines the package as
> + a virtual package, False otherwise
> +
> + :param pkg_name: The name of the package, for which to check if
> + a symbol exists defining it as a virtual package
> +
> + """
> + virt_pattern = "BR2_PACKAGE_HAS_" + pkg_name + "$"
> + virt_pattern = re.sub("_", ".", virt_pattern)
> + virt_pattern = re.compile(virt_pattern, re.IGNORECASE)
> + for sym in self.config:
> + if virt_pattern.match(sym.get_name()):
> + return True
> + return False
> +
> def _get_pkg_name(self, symbol):
> """ Return the package name of the specified symbol.
>
> --
> 1.8.3.2
>
With the typo fixed, you'll have my Acked-by.
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display virtual packages in generated lists
2014-05-31 21:19 ` Samuel Martin
@ 2014-05-31 22:38 ` Yann E. MORIN
0 siblings, 0 replies; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:38 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:19 +0200, Samuel Martin spake thusly:
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> > From: "Yann E. MORIN" <yann.morin.1998@free.fr>
> >
> > If a package has both a 'real' and a 'virtual' definition, consider it
> > is a virtual package and do not display it in the generated package list.
> >
> > This is the case for jpeg and cryptodev, that are virtual packages, but
> > also real (but empty) packages used to provide a prompt to enable/disable
> > a choice to select an implementation. In this case, we do not want to
> > list the virtul packages, but only its implementations.
>
> s/virtul/virtual/
> s/its implementations/their implementations/
Fixed.
> With the typo fixed, you'll have my Acked-by.
Added, thanks!
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (3 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 04/11 RFC] support/scripts: do not display " Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:20 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists Yann E. MORIN
` (6 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
When generating the package lists, the reponsibility to decide what is
actually a package symbol is currently split between the _is_package(),
the get_symbol_subset() and the format_asciidoc_table() funtions.
The two latter functions check that an item is really a symbol, and that
is has a prompt.
While this is currently correct for real packages, this will no longer
be the case when we also generate a list of virtual packages, since they
do not have a prompt.
Move the responsibility to verify that a symbol is indeed a package symbol
to is_package(), so it's all in one place, and makes it easier to change
for virtual packages.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index 10dbbd3..7144ca3 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -75,8 +75,6 @@ def get_symbol_subset(root, filter_func):
raise Exception(message)
for item in get_items():
if item.is_symbol():
- if not item.prompts:
- continue
if not filter_func(item):
continue
yield item
@@ -134,8 +132,6 @@ def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
return "| {0:<40}\n".format(item)
lines = []
for item in get_symbol_subset(root, filter_func):
- if not item.is_symbol() or not item.prompts:
- continue
loc = get_symbol_parents(item, root, enable_choice=enable_choice)
lines.append(_format_entry(get_label_func(item), loc, sub_menu))
if sorted:
@@ -247,6 +243,10 @@ class Buildroot:
Note: only 'real' is (implictly) handled for now
"""
+ if not symbol.is_symbol():
+ return False
+ if type == 'real' and not symbol.prompts:
+ return False
if not self.re_pkg_prefix.match(symbol.get_name()):
return False
pkg_name = self._get_pkg_name(symbol)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package
2014-05-29 20:38 ` [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package Yann E. MORIN
@ 2014-05-31 21:20 ` Samuel Martin
2014-05-31 22:39 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:20 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> When generating the package lists, the reponsibility to decide what is
s/reponsibility/responsibility/
> actually a package symbol is currently split between the _is_package(),/
> the get_symbol_subset() and the format_asciidoc_table() funtions.
>
> The two latter functions check that an item is really a symbol, and that
> is has a prompt.
>
> While this is currently correct for real packages, this will no longer
> be the case when we also generate a list of virtual packages, since they
> do not have a prompt.
>
> Move the responsibility to verify that a symbol is indeed a package symbol
> to is_package(), so it's all in one place, and makes it easier to change
s/ is_package()/ _is_package()/
> for virtual packages.
I fully agree with this! :-)
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
> ---
> support/scripts/gen-manual-lists.py | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> index 10dbbd3..7144ca3 100644
> --- a/support/scripts/gen-manual-lists.py
> +++ b/support/scripts/gen-manual-lists.py
> @@ -75,8 +75,6 @@ def get_symbol_subset(root, filter_func):
> raise Exception(message)
> for item in get_items():
> if item.is_symbol():
> - if not item.prompts:
> - continue
> if not filter_func(item):
> continue
> yield item
> @@ -134,8 +132,6 @@ def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
> return "| {0:<40}\n".format(item)
> lines = []
> for item in get_symbol_subset(root, filter_func):
> - if not item.is_symbol() or not item.prompts:
> - continue
> loc = get_symbol_parents(item, root, enable_choice=enable_choice)
> lines.append(_format_entry(get_label_func(item), loc, sub_menu))
> if sorted:
> @@ -247,6 +243,10 @@ class Buildroot:
> Note: only 'real' is (implictly) handled for now
>
> """
> + if not symbol.is_symbol():
> + return False
> + if type == 'real' and not symbol.prompts:
> + return False
> if not self.re_pkg_prefix.match(symbol.get_name()):
> return False
> pkg_name = self._get_pkg_name(symbol)
> --
> 1.8.3.2
>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package
2014-05-31 21:20 ` Samuel Martin
@ 2014-05-31 22:39 ` Yann E. MORIN
2014-06-01 15:22 ` Samuel Martin
0 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:39 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:20 +0200, Samuel Martin spake thusly:
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
[--SNIP commit log--]
Typoes fixed, thanks! :-)
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package
2014-05-31 22:39 ` Yann E. MORIN
@ 2014-06-01 15:22 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-06-01 15:22 UTC (permalink / raw)
To: buildroot
Yann,
Just caught a typo in the subject:
s/responsibile/responsible/
On Sun, Jun 1, 2014 at 12:39 AM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> Samuel, All,
>
> On 2014-05-31 23:20 +0200, Samuel Martin spake thusly:
>> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> [--SNIP commit log--]
>
> Typoes fixed, thanks! :-)
>
> Regards,
> Yann E. MORIN.
>
> --
> .-----------------.--------------------.------------------.--------------------.
> | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
> | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
> | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
> | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
> '------------------------------^-------^------------------^--------------------'
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (4 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 05/11 RFC] support/scripts: who's responsibile to decide what is a package Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:20 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 07/11 RFC] package/cryptodev: make it behave more like other virtual packages Yann E. MORIN
` (5 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Currently, we can generate two different tables of packages:
- a single-column table with the symbols' prompts,
- a two-column table with the sumbols' prompts and locations in the
menuconfig.
For virtual packages, this is not enough, since we will have to display
more columns, with different content:
- the virtual package name (but such symbols do not have a prompt)
- the symbol name
- the providers for thet virtual package
So, instead of having a single function that knows how to generate any
table, introduce a formatter function that is passed as argument to,
and called by format_asciidoc_table(). Such formatter functions are
responsible for providing:
- the layout of the table (number of columns, columns arangement),
- the formatted header line,
- a formatted line for a symbol.
What the formatter should ouput depends on its arguments:
- if none are passed, the layout is returned,
- if no symbol is passed, but the header label is, it returns
the header line,
- otherwise, it returns the formatted line for a symbol.
Two formatter functions are introduced in this changeset, to replace the
current 'sub_menu' feature:
- _format_symbol_prompt() to display a one-column table with only the
symbols' prompts,
- _format_symbol_prompt_location() to display a two-column table with
the symbols' prompts and locations.
This will help us to later introduce a new formatter to generate a table
for virtual packages.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 72 ++++++++++++++++++++++---------------
1 file changed, 43 insertions(+), 29 deletions(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index 7144ca3..8311929 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -109,50 +109,33 @@ def get_symbol_parents(item, root=None, enable_choice=False):
def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
- enable_choice=False, sorted=True, sub_menu=True,
+ format_func=lambda x: "",
+ enable_choice=False, sorted=True,
item_label=None):
""" Return the asciidoc formatted table of the items and their location.
:param root: Root item of the item subset
:param get_label_func: Item's label getter function
:param filter_func: Filter function to apply on the item subset
+ :param format_func: Function to format a symbol and the table header
:param enable_choice: Enable choices to appear as part of the item's
location
:param sorted: Flag to alphabetically sort the table
- :param sub_menu: Output the column with the sub-menu path
"""
- def _format_entry(item, parents, sub_menu):
- """ Format an asciidoc table entry.
- """
- if sub_menu:
- return "| {0:<40} <| {1}\n".format(item, " -> ".join(parents))
- else:
- return "| {0:<40}\n".format(item)
lines = []
for item in get_symbol_subset(root, filter_func):
- loc = get_symbol_parents(item, root, enable_choice=enable_choice)
- lines.append(_format_entry(get_label_func(item), loc, sub_menu))
+ lines.append(format_func(symbol=item, root=root,
+ get_label_func=get_label_func,
+ enable_choice=enable_choice))
if sorted:
lines.sort(key=lambda x: x.lower())
- if hasattr(root, "get_title"):
- loc_label = get_symbol_parents(root, None, enable_choice=enable_choice)
- loc_label += [root.get_title(), "..."]
- else:
- loc_label = ["Location"]
- if not item_label:
- item_label = "Items"
table = ":halign: center\n\n"
- if sub_menu:
- width = "100%"
- columns = "^1,4"
- else:
- width = "30%"
- columns = "^1"
+ width, columns = format_func()
table = "[width=\"{0}\",cols=\"{1}\",options=\"header\"]\n".format(width, columns)
table += "|===================================================\n"
- table += _format_entry(item_label, loc_label, sub_menu)
+ table += format_func(header=item_label, root=root)
table += "\n" + "".join(lines) + "\n"
table += "|===================================================\n"
return table
@@ -180,22 +163,22 @@ class Buildroot:
'filename': "package-list",
'root_menu': "Target packages",
'filter': "_is_real_package",
+ 'format': '_format_symbol_prompt_location',
'sorted': True,
- 'sub_menu': True,
},
'host-packages': {
'filename': "host-package-list",
'root_menu': "Host utilities",
'filter': "_is_real_package",
+ 'format': '_format_symbol_prompt',
'sorted': True,
- 'sub_menu': False,
},
'deprecated': {
'filename': "deprecated-list",
'root_menu': None,
'filter': "_is_deprecated",
+ 'format': '_format_symbol_prompt_location',
'sorted': False,
- 'sub_menu': True,
},
}
@@ -323,6 +306,36 @@ class Buildroot:
label += " *(deprecated)*"
return label
+ def _format_symbol_prompt(self, symbol=None, root=None,
+ enable_choice=False, header=None,
+ get_label_func=lambda x: "?"):
+ if symbol is None and header is None:
+ return ( "30%", "^1" )
+
+ if header is not None:
+ return "| {0:<40}\n".format(header)
+
+ return "| {0:<40}\n".format(get_label_func(symbol))
+
+ def _format_symbol_prompt_location(self, symbol=None, root=None,
+ enable_choice=False, header=None,
+ get_label_func=lambda x: "?"):
+ if symbol is None and header is None:
+ return ( "100%", "^1,4" )
+
+ if header is not None:
+ if hasattr(root, "get_title"):
+ loc_label = get_symbol_parents(root, None, enable_choice=enable_choice)
+ loc_label += [root.get_title(), "..."]
+ else:
+ loc_label = ["Location"]
+
+ return "| {0:<40} <| {1}\n".format(header, " -> ".join(loc_label))
+
+ parents = get_symbol_parents(symbol, root, enable_choice)
+ return "| {0:<40} <| {1}\n".format(get_label_func(symbol),
+ " -> ".join(parents))
+
def print_list(self, list_type, enable_choice=True, enable_deprecated=True,
dry_run=False, output=None):
""" Print the requested list. If not dry run, then the list is
@@ -355,6 +368,7 @@ class Buildroot:
root_item = self.config
filter_ = getattr(self, list_config.get('filter'))
filter_func = lambda x: filter_(x)
+ format_func = getattr(self, list_config.get('format'))
if not enable_deprecated and list_type != "deprecated":
filter_func = lambda x: filter_(x) and not self._is_deprecated(x)
mark_depr = list_type != "deprecated"
@@ -363,9 +377,9 @@ class Buildroot:
table = format_asciidoc_table(root_item, get_label,
filter_func=filter_func,
+ format_func=format_func,
enable_choice=enable_choice,
sorted=list_config.get('sorted'),
- sub_menu=list_config.get('sub_menu'),
item_label=item_label)
content = self.list_in.format(table=table)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists
2014-05-29 20:38 ` [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists Yann E. MORIN
@ 2014-05-31 21:20 ` Samuel Martin
2014-05-31 23:09 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:20 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Currently, we can generate two different tables of packages:
> - a single-column table with the symbols' prompts,
> - a two-column table with the sumbols' prompts and locations in the
s/sumbols/symbols/
> menuconfig.
>
> For virtual packages, this is not enough, since we will have to display
> more columns, with different content:
> - the virtual package name (but such symbols do not have a prompt)
> - the symbol name
> - the providers for thet virtual package
s/thet/that/
>
> So, instead of having a single function that knows how to generate any
> table, introduce a formatter function that is passed as argument to,
> and called by format_asciidoc_table(). Such formatter functions are
> responsible for providing:
> - the layout of the table (number of columns, columns arangement),
s/columns arangement/column arrangement/
> - the formatted header line,
> - a formatted line for a symbol.
>
> What the formatter should ouput depends on its arguments:
> - if none are passed, the layout is returned,
> - if no symbol is passed, but the header label is, it returns
> the header line,
> - otherwise, it returns the formatted line for a symbol.
The more I think about this, the more I feel it fragile (i.e. using 2
variables for a tristate) :-/
In the end, the header argument and the symbol one are just some data
processed by the formatter.
Maybe we should just replace the header and symbol kwargs by a data
one, and add another argument telling what should return the
formatter: either the layout, the header line or a symbol line.
>
> Two formatter functions are introduced in this changeset, to replace the
> current 'sub_menu' feature:
> - _format_symbol_prompt() to display a one-column table with only the
> symbols' prompts,
> - _format_symbol_prompt_location() to display a two-column table with
> the symbols' prompts and locations.
>
> This will help us to later introduce a new formatter to generate a table
> for virtual packages.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
> ---
> support/scripts/gen-manual-lists.py | 72 ++++++++++++++++++++++---------------
> 1 file changed, 43 insertions(+), 29 deletions(-)
>
> diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> index 7144ca3..8311929 100644
> --- a/support/scripts/gen-manual-lists.py
> +++ b/support/scripts/gen-manual-lists.py
> @@ -109,50 +109,33 @@ def get_symbol_parents(item, root=None, enable_choice=False):
>
>
> def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
> - enable_choice=False, sorted=True, sub_menu=True,
> + format_func=lambda x: "",
usually for default lambda function, I set: lambda x: x
> + enable_choice=False, sorted=True,
> item_label=None):
> """ Return the asciidoc formatted table of the items and their location.
>
> :param root: Root item of the item subset
> :param get_label_func: Item's label getter function
> :param filter_func: Filter function to apply on the item subset
> + :param format_func: Function to format a symbol and the table header
> :param enable_choice: Enable choices to appear as part of the item's
> location
> :param sorted: Flag to alphabetically sort the table
> - :param sub_menu: Output the column with the sub-menu path
>
> """
> - def _format_entry(item, parents, sub_menu):
> - """ Format an asciidoc table entry.
>
> - """
> - if sub_menu:
> - return "| {0:<40} <| {1}\n".format(item, " -> ".join(parents))
> - else:
> - return "| {0:<40}\n".format(item)
> lines = []
> for item in get_symbol_subset(root, filter_func):
> - loc = get_symbol_parents(item, root, enable_choice=enable_choice)
> - lines.append(_format_entry(get_label_func(item), loc, sub_menu))
> + lines.append(format_func(symbol=item, root=root,
> + get_label_func=get_label_func,
> + enable_choice=enable_choice))
> if sorted:
> lines.sort(key=lambda x: x.lower())
> - if hasattr(root, "get_title"):
> - loc_label = get_symbol_parents(root, None, enable_choice=enable_choice)
> - loc_label += [root.get_title(), "..."]
> - else:
> - loc_label = ["Location"]
> - if not item_label:
> - item_label = "Items"
> table = ":halign: center\n\n"
> - if sub_menu:
> - width = "100%"
> - columns = "^1,4"
> - else:
> - width = "30%"
> - columns = "^1"
> + width, columns = format_func()
> table = "[width=\"{0}\",cols=\"{1}\",options=\"header\"]\n".format(width, columns)
> table += "|===================================================\n"
> - table += _format_entry(item_label, loc_label, sub_menu)
> + table += format_func(header=item_label, root=root)
> table += "\n" + "".join(lines) + "\n"
> table += "|===================================================\n"
> return table
> @@ -180,22 +163,22 @@ class Buildroot:
> 'filename': "package-list",
> 'root_menu': "Target packages",
> 'filter': "_is_real_package",
> + 'format': '_format_symbol_prompt_location',
For dictionary, usually, single-quotes are used for the key and
double-quotes for the value (when it's a string), though both single
and double quote can be used in both cases (key and value).
Here my point is more about consistency with the rest of the file.
> 'sorted': True,
> - 'sub_menu': True,
> },
> 'host-packages': {
> 'filename': "host-package-list",
> 'root_menu': "Host utilities",
> 'filter': "_is_real_package",
> + 'format': '_format_symbol_prompt',
ditto
> 'sorted': True,
> - 'sub_menu': False,
> },
> 'deprecated': {
> 'filename': "deprecated-list",
> 'root_menu': None,
> 'filter': "_is_deprecated",
> + 'format': '_format_symbol_prompt_location',
ditto
> 'sorted': False,
> - 'sub_menu': True,
> },
> }
>
> @@ -323,6 +306,36 @@ class Buildroot:
> label += " *(deprecated)*"
> return label
>
> + def _format_symbol_prompt(self, symbol=None, root=None,
> + enable_choice=False, header=None,
> + get_label_func=lambda x: "?"):
default lambda: s/"?"/x/
> + if symbol is None and header is None:
> + return ( "30%", "^1" )
> +
> + if header is not None:
> + return "| {0:<40}\n".format(header)
> +
> + return "| {0:<40}\n".format(get_label_func(symbol))
> +
> + def _format_symbol_prompt_location(self, symbol=None, root=None,
> + enable_choice=False, header=None,
> + get_label_func=lambda x: "?"):
ditto
> + if symbol is None and header is None:
> + return ( "100%", "^1,4" )
> +
> + if header is not None:
> + if hasattr(root, "get_title"):
> + loc_label = get_symbol_parents(root, None, enable_choice=enable_choice)
> + loc_label += [root.get_title(), "..."]
> + else:
> + loc_label = ["Location"]
> +
> + return "| {0:<40} <| {1}\n".format(header, " -> ".join(loc_label))
> +
> + parents = get_symbol_parents(symbol, root, enable_choice)
> + return "| {0:<40} <| {1}\n".format(get_label_func(symbol),
> + " -> ".join(parents))
> +
> def print_list(self, list_type, enable_choice=True, enable_deprecated=True,
> dry_run=False, output=None):
> """ Print the requested list. If not dry run, then the list is
> @@ -355,6 +368,7 @@ class Buildroot:
> root_item = self.config
> filter_ = getattr(self, list_config.get('filter'))
> filter_func = lambda x: filter_(x)
> + format_func = getattr(self, list_config.get('format'))
> if not enable_deprecated and list_type != "deprecated":
> filter_func = lambda x: filter_(x) and not self._is_deprecated(x)
> mark_depr = list_type != "deprecated"
> @@ -363,9 +377,9 @@ class Buildroot:
>
> table = format_asciidoc_table(root_item, get_label,
> filter_func=filter_func,
> + format_func=format_func,
> enable_choice=enable_choice,
> sorted=list_config.get('sorted'),
> - sub_menu=list_config.get('sub_menu'),
> item_label=item_label)
>
> content = self.list_in.format(table=table)
> --
> 1.8.3.2
>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists
2014-05-31 21:20 ` Samuel Martin
@ 2014-05-31 23:09 ` Yann E. MORIN
2014-06-01 15:45 ` Samuel Martin
0 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 23:09 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:20 +0200, Samuel Martin spake thusly:
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
[--SNIP--]
Typoes fixed.
> > What the formatter should ouput depends on its arguments:
> > - if none are passed, the layout is returned,
> > - if no symbol is passed, but the header label is, it returns
> > the header line,
> > - otherwise, it returns the formatted line for a symbol.
>
> The more I think about this, the more I feel it fragile (i.e. using 2
> variables for a tristate) :-/
> In the end, the header argument and the symbol one are just some data
> processed by the formatter.
> Maybe we should just replace the header and symbol kwargs by a data
> one, and add another argument telling what should return the
> formatter: either the layout, the header line or a symbol line.
OK, I see what you mean. Something like the following?
format_symbol_prompt(self, what=None, symbol=None, header=None,
root=None, enable_choice=False, header=None,
get_label_func=lambda x: "?"):
if what is None:
throw an exception
if what == "layout":
return ("bla","bla")
if what == "header":
return formated_header(header)
if what == "symbol":
return formated_symbol(symbol)
throw an exception
However, I don;t get what you mean by "a data argument". Do you mean a
kind of casting the arg whether we're asked to render a header or a
symbol? How does one casts in Python?
Oh wait, duck-typing, right?
[--SNIP--]
> > diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> > index 7144ca3..8311929 100644
> > --- a/support/scripts/gen-manual-lists.py
> > +++ b/support/scripts/gen-manual-lists.py
> > @@ -109,50 +109,33 @@ def get_symbol_parents(item, root=None, enable_choice=False):
> >
> >
> > def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
> > - enable_choice=False, sorted=True, sub_menu=True,
> > + format_func=lambda x: "",
>
> usually for default lambda function, I set: lambda x: x
But I do not want it to return anything, I want it to return a string.
Or do you expect that an exception would be thrown out in case an object
is used that is not a string later in the call chain? I don't like that
too much...
Alternatively, as Maxime said on IRC, I coiuld just set it to None, and
get an exception if it is no passed by the caller.
Except (aha!) setting it to a lambda makes it explicit it has to be a
function.
So, OK, I'll use your default lambda. At least, we'd get an exception if
someone forgets to pass the function.
> > @@ -180,22 +163,22 @@ class Buildroot:
> > 'filename': "package-list",
> > 'root_menu': "Target packages",
> > 'filter': "_is_real_package",
> > + 'format': '_format_symbol_prompt_location',
>
> For dictionary, usually, single-quotes are used for the key and
> double-quotes for the value (when it's a string), though both single
> and double quote can be used in both cases (key and value).
> Here my point is more about consistency with the rest of the file.
Yep, fixed the three.
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists
2014-05-31 23:09 ` Yann E. MORIN
@ 2014-06-01 15:45 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-06-01 15:45 UTC (permalink / raw)
To: buildroot
Yann,
On Sun, Jun 1, 2014 at 1:09 AM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> Samuel, All,
>
> On 2014-05-31 23:20 +0200, Samuel Martin spake thusly:
>> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> [--SNIP--]
>
> Typoes fixed.
>
>> > What the formatter should ouput depends on its arguments:
>> > - if none are passed, the layout is returned,
>> > - if no symbol is passed, but the header label is, it returns
>> > the header line,
>> > - otherwise, it returns the formatted line for a symbol.
>>
>> The more I think about this, the more I feel it fragile (i.e. using 2
>> variables for a tristate) :-/
>> In the end, the header argument and the symbol one are just some data
>> processed by the formatter.
>> Maybe we should just replace the header and symbol kwargs by a data
>> one, and add another argument telling what should return the
>> formatter: either the layout, the header line or a symbol line.
>
> OK, I see what you mean. Something like the following?
>
> format_symbol_prompt(self, what=None, symbol=None, header=None,
> root=None, enable_choice=False, header=None,
> get_label_func=lambda x: "?"):
> if what is None:
> throw an exception
> if what == "layout":
> return ("bla","bla")
> if what == "header":
> return formated_header(header)
> if what == "symbol":
> return formated_symbol(symbol)
> throw an exception
>
> However, I don;t get what you mean by "a data argument". Do you mean a
> kind of casting the arg whether we're asked to render a header or a
> symbol? How does one casts in Python?
By "a data argument" I mean:
format_symbol_prompt(self, what=None, data=None,
root=None, enable_choice=False,
get_label_func=lambda x: "?"):
if what is None:
throw an exception
if what == "layout":
return ("bla","bla")
if what == "header":
return formated_header(data)
if what == "symbol":
return formated_symbol(data)
raise Exception("Unsupported argument 'what': %s" % what)
For the cast, python does magics with its PyObjects.
If you want to be sure to return a string from any object, you can do:
return str(data)
>
> Oh wait, duck-typing, right?
>
> [--SNIP--]
>> > diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
>> > index 7144ca3..8311929 100644
>> > --- a/support/scripts/gen-manual-lists.py
>> > +++ b/support/scripts/gen-manual-lists.py
>> > @@ -109,50 +109,33 @@ def get_symbol_parents(item, root=None, enable_choice=False):
>> >
>> >
>> > def format_asciidoc_table(root, get_label_func, filter_func=lambda x: True,
>> > - enable_choice=False, sorted=True, sub_menu=True,
>> > + format_func=lambda x: "",
>>
>> usually for default lambda function, I set: lambda x: x
>
> But I do not want it to return anything, I want it to return a string.
See above ;-)
>
> Or do you expect that an exception would be thrown out in case an object
> is used that is not a string later in the call chain? I don't like that
> too much...
>
> Alternatively, as Maxime said on IRC, I coiuld just set it to None, and
> get an exception if it is no passed by the caller.
>
> Except (aha!) setting it to a lambda makes it explicit it has to be a
> function.
>
> So, OK, I'll use your default lambda. At least, we'd get an exception if
> someone forgets to pass the function.
>
>> > @@ -180,22 +163,22 @@ class Buildroot:
>> > 'filename': "package-list",
>> > 'root_menu': "Target packages",
>> > 'filter': "_is_real_package",
>> > + 'format': '_format_symbol_prompt_location',
>>
>> For dictionary, usually, single-quotes are used for the key and
>> double-quotes for the value (when it's a string), though both single
>> and double quote can be used in both cases (key and value).
>> Here my point is more about consistency with the rest of the file.
>
> Yep, fixed the three.
>
> Regards,
> Yann E. MORIN.
>
> --
> .-----------------.--------------------.------------------.--------------------.
> | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
> | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
> | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
> | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
> '------------------------------^-------^------------------^--------------------'
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 07/11 RFC] package/cryptodev: make it behave more like other virtual packages
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (5 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 06/11 RFC] support/scripts: introduce a symbol formatter to generate package lists Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:21 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 08/11 RFC] package/jpeg: " Yann E. MORIN
` (4 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Currently, the virtual package cryptodev is a special virtual package,
as it offers a choice for its implementation, rather than letting the
user enable them manually.
In so doing, it defines its _HAS option as a 'def_bool y' rather than
letting each implementation 'select' it.
Since we are going to generate a list of virtual packages and their
providers, this defeats the heuristic used to find providers.
Coming with an alternate heuristic that also matches the cryptodev
package is quite complex, so better and easier to make it look more
like any other virtual package.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Samuel Martin <s.martin49@gmail.com>
---
package/cryptodev/Config.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/package/cryptodev/Config.in b/package/cryptodev/Config.in
index 2407e04..9f9df02 100644
--- a/package/cryptodev/Config.in
+++ b/package/cryptodev/Config.in
@@ -18,6 +18,7 @@ choice
config BR2_PACKAGE_CRYPTODEV_LINUX
bool "cryptodev-linux"
depends on !BR2_microblaze
+ select BR2_PACKAGE_HAS_CRYPTODEV
help
Cryptodev-linux is a device that allows access to Linux kernel
cryptographic drivers; thus allowing userspace applications
@@ -27,6 +28,7 @@ config BR2_PACKAGE_CRYPTODEV_LINUX
config BR2_PACKAGE_OCF_LINUX
bool "ocf-linux"
+ select BR2_PACKAGE_HAS_CRYPTODEV
help
OCF-Linux is a Linux port of the OpenBSD/FreeBSD Cryptographic
Framework (OCF). This port aims to bring full asynchronous HW/SW
@@ -38,7 +40,7 @@ config BR2_PACKAGE_OCF_LINUX
endchoice
config BR2_PACKAGE_HAS_CRYPTODEV
- def_bool y
+ bool
config BR2_PACKAGE_PROVIDES_CRYPTODEV
string
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 07/11 RFC] package/cryptodev: make it behave more like other virtual packages
2014-05-29 20:38 ` [Buildroot] [PATCH 07/11 RFC] package/cryptodev: make it behave more like other virtual packages Yann E. MORIN
@ 2014-05-31 21:21 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:21 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Currently, the virtual package cryptodev is a special virtual package,
> as it offers a choice for its implementation, rather than letting the
> user enable them manually.
>
> In so doing, it defines its _HAS option as a 'def_bool y' rather than
> letting each implementation 'select' it.
>
> Since we are going to generate a list of virtual packages and their
> providers, this defeats the heuristic used to find providers.
>
> Coming with an alternate heuristic that also matches the cryptodev
> package is quite complex, so better and easier to make it look more
> like any other virtual package.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Samuel Martin <s.martin49@gmail.com>
Reviewed-by: Samuel Martin <s.martin49@gmail.com>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 08/11 RFC] package/jpeg: make it behave more like other virtual packages
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (6 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 07/11 RFC] package/cryptodev: make it behave more like other virtual packages Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:21 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 09/11 RFC] package/mesa3d: rename the prompt Yann E. MORIN
` (3 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Currently, the virtual package jpeg is a special virtual package,
as it offers a choice for its implementation, rather than letting the
user enable them manually.
In so doing, it defines its _HAS option as a 'def_bool y' rather than
letting each implementation 'select' it.
Since we are going to generate a list of virtual packages and their
providers, this defeats the heuristic used to find providers.
Coming with an alternate heuristic that also matches the jpeg
package is quite complex, so better and easier to make it look more
like any other virtual package.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Samuel Martin <s.martin49@gmail.com>
---
package/jpeg/Config.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/package/jpeg/Config.in b/package/jpeg/Config.in
index 3042d24..f337aeb 100644
--- a/package/jpeg/Config.in
+++ b/package/jpeg/Config.in
@@ -13,6 +13,7 @@ choice
config BR2_PACKAGE_LIBJPEG
bool "jpeg"
+ select BR2_PACKAGE_HAS_JPEG
help
The ubiquitous C library for manipulating JPEG images.
@@ -20,6 +21,7 @@ config BR2_PACKAGE_LIBJPEG
config BR2_PACKAGE_JPEG_TURBO
bool "jpeg-turbo"
+ select BR2_PACKAGE_HAS_JPEG
help
Libjpeg-turbo is a derivative of libjpeg that uses SIMD
instructions (MMX, SSE2, NEON) to accelerate baseline JPEG
@@ -31,7 +33,7 @@ config BR2_PACKAGE_JPEG_TURBO
endchoice
config BR2_PACKAGE_HAS_JPEG
- def_bool y
+ bool
config BR2_PACKAGE_PROVIDES_JPEG
string
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 08/11 RFC] package/jpeg: make it behave more like other virtual packages
2014-05-29 20:38 ` [Buildroot] [PATCH 08/11 RFC] package/jpeg: " Yann E. MORIN
@ 2014-05-31 21:21 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:21 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Currently, the virtual package jpeg is a special virtual package,
> as it offers a choice for its implementation, rather than letting the
> user enable them manually.
>
> In so doing, it defines its _HAS option as a 'def_bool y' rather than
> letting each implementation 'select' it.
>
> Since we are going to generate a list of virtual packages and their
> providers, this defeats the heuristic used to find providers.
>
> Coming with an alternate heuristic that also matches the jpeg
> package is quite complex, so better and easier to make it look more
> like any other virtual package.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Samuel Martin <s.martin49@gmail.com>
Reviewed-by: Samuel Martin <s.martin49@gmail.com>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 09/11 RFC] package/mesa3d: rename the prompt
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (7 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 08/11 RFC] package/jpeg: " Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:21 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages Yann E. MORIN
` (2 subsequent siblings)
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Rename the prompt for mesa3d so that it matches what we usually do
for prompts of packages: just name the package in lower case.
This will help generate nicer tables in the generated packages list,
both existing tables, and the upcoming table of virtual packages.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Samuel Martin <s.martin49@gmail.com>
---
package/mesa3d/Config.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package/mesa3d/Config.in b/package/mesa3d/Config.in
index 06f2bc3..6621154 100644
--- a/package/mesa3d/Config.in
+++ b/package/mesa3d/Config.in
@@ -1,5 +1,5 @@
menuconfig BR2_PACKAGE_MESA3D
- bool "Mesa 3D Graphics Library"
+ bool "mesa3d"
select BR2_PACKAGE_LIBDRM
select BR2_PACKAGE_EXPAT
select BR2_PACKAGE_HOST_LIBXML2_PYTHON
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 09/11 RFC] package/mesa3d: rename the prompt
2014-05-29 20:38 ` [Buildroot] [PATCH 09/11 RFC] package/mesa3d: rename the prompt Yann E. MORIN
@ 2014-05-31 21:21 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:21 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Rename the prompt for mesa3d so that it matches what we usually do
> for prompts of packages: just name the package in lower case.
>
> This will help generate nicer tables in the generated packages list,
> both existing tables, and the upcoming table of virtual packages.
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Samuel Martin <s.martin49@gmail.com>
Reviewed-by: Samuel Martin <s.martin49@gmail.com>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (8 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 09/11 RFC] package/mesa3d: rename the prompt Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:25 ` Samuel Martin
2014-05-29 20:38 ` [Buildroot] [PATCH 11/11 RFC] docs/manual: add the virtual packages list Yann E. MORIN
2014-05-31 21:18 ` [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Samuel Martin
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Generate an asciidoc table that can be included in the manual, that
lists the existing virtual packages, the corresponding symbol, and
their providers (and sub-options thereof).
The core of this change is the addition of a new formatter for virtual
packages. This formatter is a bit tricky, as it has to catter for a
bumch of corner cases:
- provider is not a package, but sub-options of a package
- such a sub-option may be itself 'select'-ed by one or more
other sub-option
- legacy packages should not be considered as a provider
Those cases are real:
- sub-options of mesa3d provide EGL or GLES
- selected sub-options of mesa3d provide GL
- udev is a legacy package, but it provides udev
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
support/scripts/gen-manual-lists.py | 84 ++++++++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
index 8311929..7a4f403 100644
--- a/support/scripts/gen-manual-lists.py
+++ b/support/scripts/gen-manual-lists.py
@@ -173,6 +173,13 @@ class Buildroot:
'format': '_format_symbol_prompt',
'sorted': True,
},
+ 'virtual-packages': {
+ 'filename': "virtual-package-list",
+ 'root_menu': "Target packages",
+ 'filter': "_is_virtual_package",
+ 'format': '_format_symbol_virtual',
+ 'sorted': True,
+ },
'deprecated': {
'filename': "deprecated-list",
'root_menu': None,
@@ -230,6 +237,8 @@ class Buildroot:
return False
if type == 'real' and not symbol.prompts:
return False
+ if type == 'virtual' and symbol.prompts:
+ return False
if not self.re_pkg_prefix.match(symbol.get_name()):
return False
pkg_name = self._get_pkg_name(symbol)
@@ -264,11 +273,17 @@ class Buildroot:
if type == 'real' or type == 'both':
if pattern.match(pkg) and not self._exists_virt_symbol(pkg):
return True
+ if type == 'virtual' or type == 'both':
+ if pattern.match('has_' + pkg):
+ return True
return False
def _is_real_package(self, symbol):
return self._is_package(symbol, 'real')
+ def _is_virtual_package(self, symbol):
+ return self._is_package(symbol, 'virtual')
+
def _exists_virt_symbol(self, pkg_name):
""" Return True if a symbol exists that defines the package as
a virtual package, False otherwise
@@ -336,6 +351,71 @@ class Buildroot:
return "| {0:<40} <| {1}\n".format(get_label_func(symbol),
" -> ".join(parents))
+ def _format_symbol_virtual(self, symbol=None, root=None,
+ enable_choice=False, header=None,
+ get_label_func=lambda x: "?"):
+ def _symbol_is_legacy(symbol):
+ selects = symbol.get_selected_symbols()
+ if not selects:
+ return False
+ for s in selects:
+ if s.get_name() == "BR2_LEGACY":
+ return True
+ return False
+
+ def _get_parent_package(br, sym):
+ if br._is_real_package(sym):
+ return None
+ # Trim the symbol name from its last component (separated with
+ # underscores), until we either find a symbol which is a real
+ # package, or until we have no cpmponent (i.e. just 'BR2')
+ name = sym.get_name()
+ while name != "BR2":
+ name = re.sub(r"_[^_]+$", r"", name)
+ s = br.config.get_symbol(name)
+ if s is None:
+ continue
+ if br._is_real_package(s):
+ return s
+ return None
+
+ def _get_providers(br, config, symbol):
+ providers = list()
+ for sym in self.config:
+ if not sym.is_symbol():
+ continue
+ selects = sym.get_selected_symbols()
+ if not selects:
+ continue
+ for s in selects:
+ if s == symbol:
+ if _symbol_is_legacy(sym):
+ continue
+ if sym.prompts:
+ l = self._get_symbol_label(sym,False)
+ parent_pkg = _get_parent_package(br, sym)
+ if parent_pkg is not None:
+ l = self._get_symbol_label(parent_pkg, False) \
+ + " (w/ " + l + ")"
+ providers.append(l)
+ else:
+ providers.extend(_get_providers(br,config,sym))
+ return providers
+
+ if symbol is None and header is None:
+ return ( "100%", "^1,4,4" )
+
+ if header is not None:
+ return "| {0:<20} <| {1:<32} <| Providers\n".format("Virtual packages", "Symbols")
+
+ pkg = re.sub(r"^BR2_PACKAGE_HAS_(.+)$", r"\1", symbol.get_name())
+ providers = _get_providers(self, self.config, symbol)
+
+ return "| {0:<20} <| {1:<32} <| {2}\n".format(pkg.lower(),
+ '+' + symbol.get_name() + '+',
+ ", ".join(providers))
+
+
def print_list(self, list_type, enable_choice=True, enable_deprecated=True,
dry_run=False, output=None):
""" Print the requested list. If not dry run, then the list is
@@ -404,7 +484,7 @@ class Buildroot:
if __name__ == '__main__':
- list_types = ['target-packages', 'host-packages', 'deprecated']
+ list_types = ['target-packages', 'host-packages', 'virtual-packages', 'deprecated']
parser = ArgumentParser()
parser.add_argument("list_type", nargs="?", choices=list_types,
help="""\
@@ -415,6 +495,8 @@ Generate the given list (generate all lists if unspecified)""")
help="Output target package file")
parser.add_argument("--output-host", dest="output_host",
help="Output host package file")
+ parser.add_argument("--output-virtual", dest="output_virtual",
+ help="Output virtual package file")
parser.add_argument("--output-deprecated", dest="output_deprecated",
help="Output deprecated file")
args = parser.parse_args()
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages
2014-05-29 20:38 ` [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages Yann E. MORIN
@ 2014-05-31 21:25 ` Samuel Martin
2014-05-31 22:44 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:25 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Generate an asciidoc table that can be included in the manual, that
> lists the existing virtual packages, the corresponding symbol, and
> their providers (and sub-options thereof).
>
> The core of this change is the addition of a new formatter for virtual
> packages. This formatter is a bit tricky, as it has to catter for a
> bumch of corner cases:
s/bumch/bunch/
> - provider is not a package, but sub-options of a package
> - such a sub-option may be itself 'select'-ed by one or more
> other sub-option
s/sub-option/sub-options/
> - legacy packages should not be considered as a provider
>
> Those cases are real:
> - sub-options of mesa3d provide EGL or GLES
> - selected sub-options of mesa3d provide GL
> - udev is a legacy package, but it provides udev
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
> ---
> support/scripts/gen-manual-lists.py | 84 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> index 8311929..7a4f403 100644
> --- a/support/scripts/gen-manual-lists.py
> +++ b/support/scripts/gen-manual-lists.py
> @@ -173,6 +173,13 @@ class Buildroot:
> 'format': '_format_symbol_prompt',
> 'sorted': True,
> },
> + 'virtual-packages': {
> + 'filename': "virtual-package-list",
> + 'root_menu': "Target packages",
> + 'filter': "_is_virtual_package",
> + 'format': '_format_symbol_virtual',
For dictionnary, usually, single-quotes are used for the key and
double-quotes for the value (when it's a string), though both single
and double quote can be used in both cases (key and value).
Here my point is more about consistency with the rest of the file.
> + 'sorted': True,
> + },
> 'deprecated': {
> 'filename': "deprecated-list",
> 'root_menu': None,
> @@ -230,6 +237,8 @@ class Buildroot:
> return False
> if type == 'real' and not symbol.prompts:
> return False
> + if type == 'virtual' and symbol.prompts:
> + return False
> if not self.re_pkg_prefix.match(symbol.get_name()):
> return False
> pkg_name = self._get_pkg_name(symbol)
> @@ -264,11 +273,17 @@ class Buildroot:
> if type == 'real' or type == 'both':
> if pattern.match(pkg) and not self._exists_virt_symbol(pkg):
> return True
> + if type == 'virtual' or type == 'both':
> + if pattern.match('has_' + pkg):
> + return True
Side note: is 'both' type really needed?
AFAICS, _is_package is never called with type="both".
> return False
>
> def _is_real_package(self, symbol):
> return self._is_package(symbol, 'real')
>
> + def _is_virtual_package(self, symbol):
> + return self._is_package(symbol, 'virtual')
> +
> def _exists_virt_symbol(self, pkg_name):
> """ Return True if a symbol exists that defines the package as
> a virtual package, False otherwise
> @@ -336,6 +351,71 @@ class Buildroot:
> return "| {0:<40} <| {1}\n".format(get_label_func(symbol),
> " -> ".join(parents))
>
> + def _format_symbol_virtual(self, symbol=None, root=None,
> + enable_choice=False, header=None,
> + get_label_func=lambda x: "?"):
> + def _symbol_is_legacy(symbol):
> + selects = symbol.get_selected_symbols()
> + if not selects:
> + return False
> + for s in selects:
> + if s.get_name() == "BR2_LEGACY":
> + return True
> + return False
Could be written/reduced like this:
def _symbol_is_legacy(symbol):
selects = [ s.get_name() for s in symbol.get_selected_symbols() ]
if not selects:
return False
if "BR2_LEGACY" in selects:
return True
return False
or even:
def _symbol_is_legacy(symbol):
selects = [ s.get_name() for s in symbol.get_selected_symbols() ]
return ("BR2_LEGACY" in selects)
> +
> + def _get_parent_package(br, sym):
> + if br._is_real_package(sym):
> + return None
> + # Trim the symbol name from its last component (separated with
> + # underscores), until we either find a symbol which is a real
> + # package, or until we have no cpmponent (i.e. just 'BR2')
s/cpmponent/component/
> + name = sym.get_name()
> + while name != "BR2":
> + name = re.sub(r"_[^_]+$", r"", name)
Could also be done like this:
name = name.rsplit("_", 1)[0]
> + s = br.config.get_symbol(name)
> + if s is None:
> + continue
> + if br._is_real_package(s):
> + return s
> + return None
> +
> + def _get_providers(br, config, symbol):
> + providers = list()
> + for sym in self.config:
> + if not sym.is_symbol():
> + continue
> + selects = sym.get_selected_symbols()
> + if not selects:
> + continue
> + for s in selects:
> + if s == symbol:
> + if _symbol_is_legacy(sym):
> + continue
> + if sym.prompts:
> + l = self._get_symbol_label(sym,False)
> + parent_pkg = _get_parent_package(br, sym)
> + if parent_pkg is not None:
> + l = self._get_symbol_label(parent_pkg, False) \
> + + " (w/ " + l + ")"
> + providers.append(l)
> + else:
> + providers.extend(_get_providers(br,config,sym))
> + return providers
In these 2 above sub-functions, you can replace br by self, so drop
the br argument
> +
> + if symbol is None and header is None:
> + return ( "100%", "^1,4,4" )
> +
> + if header is not None:
> + return "| {0:<20} <| {1:<32} <| Providers\n".format("Virtual packages", "Symbols")
> +
> + pkg = re.sub(r"^BR2_PACKAGE_HAS_(.+)$", r"\1", symbol.get_name())
> + providers = _get_providers(self, self.config, symbol)
> +
> + return "| {0:<20} <| {1:<32} <| {2}\n".format(pkg.lower(),
> + '+' + symbol.get_name() + '+',
> + ", ".join(providers))
> +
> +
> def print_list(self, list_type, enable_choice=True, enable_deprecated=True,
> dry_run=False, output=None):
> """ Print the requested list. If not dry run, then the list is
> @@ -404,7 +484,7 @@ class Buildroot:
>
>
> if __name__ == '__main__':
> - list_types = ['target-packages', 'host-packages', 'deprecated']
> + list_types = ['target-packages', 'host-packages', 'virtual-packages', 'deprecated']
> parser = ArgumentParser()
> parser.add_argument("list_type", nargs="?", choices=list_types,
> help="""\
> @@ -415,6 +495,8 @@ Generate the given list (generate all lists if unspecified)""")
> help="Output target package file")
> parser.add_argument("--output-host", dest="output_host",
> help="Output host package file")
> + parser.add_argument("--output-virtual", dest="output_virtual",
> + help="Output virtual package file")
> parser.add_argument("--output-deprecated", dest="output_deprecated",
> help="Output deprecated file")
> args = parser.parse_args()
> --
> 1.8.3.2
>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages
2014-05-31 21:25 ` Samuel Martin
@ 2014-05-31 22:44 ` Yann E. MORIN
2014-05-31 22:49 ` Yann E. MORIN
0 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:44 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:25 +0200, Samuel Martin spake thusly:
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
[--SNIP commit log--]
Typoes fixed.
> > diff --git a/support/scripts/gen-manual-lists.py b/support/scripts/gen-manual-lists.py
> > index 8311929..7a4f403 100644
> > --- a/support/scripts/gen-manual-lists.py
> > +++ b/support/scripts/gen-manual-lists.py
> > @@ -173,6 +173,13 @@ class Buildroot:
> > 'format': '_format_symbol_prompt',
> > 'sorted': True,
> > },
> > + 'virtual-packages': {
> > + 'filename': "virtual-package-list",
> > + 'root_menu': "Target packages",
> > + 'filter': "_is_virtual_package",
> > + 'format': '_format_symbol_virtual',
>
> For dictionnary, usually, single-quotes are used for the key and
> double-quotes for the value (when it's a string), though both single
> and double quote can be used in both cases (key and value).
> Here my point is more about consistency with the rest of the file.
Fixed.
[--SNIP--]
> > @@ -264,11 +273,17 @@ class Buildroot:
> > if type == 'real' or type == 'both':
> > if pattern.match(pkg) and not self._exists_virt_symbol(pkg):
> > return True
> > + if type == 'virtual' or type == 'both':
> > + if pattern.match('has_' + pkg):
> > + return True
>
> Side note: is 'both' type really needed?
> AFAICS, _is_package is never called with type="both".
Already removed from the previous patch.
> > @@ -336,6 +351,71 @@ class Buildroot:
> > return "| {0:<40} <| {1}\n".format(get_label_func(symbol),
> > " -> ".join(parents))
> >
> > + def _format_symbol_virtual(self, symbol=None, root=None,
> > + enable_choice=False, header=None,
> > + get_label_func=lambda x: "?"):
> > + def _symbol_is_legacy(symbol):
> > + selects = symbol.get_selected_symbols()
> > + if not selects:
> > + return False
> > + for s in selects:
> > + if s.get_name() == "BR2_LEGACY":
> > + return True
> > + return False
>
> Could be written/reduced like this:
>
> def _symbol_is_legacy(symbol):
> selects = [ s.get_name() for s in symbol.get_selected_symbols() ]
> if not selects:
> return False
> if "BR2_LEGACY" in selects:
> return True
> return False
>
> or even:
>
> def _symbol_is_legacy(symbol):
> selects = [ s.get_name() for s in symbol.get_selected_symbols() ]
> return ("BR2_LEGACY" in selects)
OK, I took your second proposal.
> > +
> > + def _get_parent_package(br, sym):
> > + if br._is_real_package(sym):
> > + return None
> > + # Trim the symbol name from its last component (separated with
> > + # underscores), until we either find a symbol which is a real
> > + # package, or until we have no cpmponent (i.e. just 'BR2')
>
> s/cpmponent/component/
Fixed.
> > + name = sym.get_name()
> > + while name != "BR2":
> > + name = re.sub(r"_[^_]+$", r"", name)
>
> Could also be done like this:
> name = name.rsplit("_", 1)[0]
Done.
> > + s = br.config.get_symbol(name)
> > + if s is None:
> > + continue
> > + if br._is_real_package(s):
> > + return s
> > + return None
> > +
> > + def _get_providers(br, config, symbol):
> > + providers = list()
> > + for sym in self.config:
> > + if not sym.is_symbol():
> > + continue
> > + selects = sym.get_selected_symbols()
> > + if not selects:
> > + continue
> > + for s in selects:
> > + if s == symbol:
> > + if _symbol_is_legacy(sym):
> > + continue
> > + if sym.prompts:
> > + l = self._get_symbol_label(sym,False)
> > + parent_pkg = _get_parent_package(br, sym)
> > + if parent_pkg is not None:
> > + l = self._get_symbol_label(parent_pkg, False) \
> > + + " (w/ " + l + ")"
> > + providers.append(l)
> > + else:
> > + providers.extend(_get_providers(br,config,sym))
> > + return providers
>
> In these 2 above sub-functions, you can replace br by self, so drop
> the br argument
Does not work:
TypeError: _get_providers() takes exactly 2 arguments (3 given)
Do I need to call it from self?
providers.extend(self._get_providers(config,sym))
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages
2014-05-31 22:44 ` Yann E. MORIN
@ 2014-05-31 22:49 ` Yann E. MORIN
0 siblings, 0 replies; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:49 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-06-01 00:44 +0200, Yann E. MORIN spake thusly:
> On 2014-05-31 23:25 +0200, Samuel Martin spake thusly:
> > In these 2 above sub-functions, you can replace br by self, so drop
> > the br argument
>
> Does not work:
> TypeError: _get_providers() takes exactly 2 arguments (3 given)
>
> Do I need to call it from self?
> providers.extend(self._get_providers(config,sym))
Forget it, I missed changing one of the callers... Works now.
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 11/11 RFC] docs/manual: add the virtual packages list
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (9 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 10/11 RFC] support/scripts: generate a list of virtual packages Yann E. MORIN
@ 2014-05-29 20:38 ` Yann E. MORIN
2014-05-31 21:25 ` Samuel Martin
2014-05-31 21:18 ` [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Samuel Martin
11 siblings, 1 reply; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-29 20:38 UTC (permalink / raw)
To: buildroot
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Add the list of virtual packages as an appendix to the manual.
Also reference this list from appropriate locations elsewhere in
the manual:
- in section 7.2.2. "Config.in file", after the existing explanations
on dependencies on target and toolchain options, a linux kernel, and
udev /dev management,
- in section 7.2.10. "Infrastructure for virtual packages", in the
provider Config.in and .mk explanations, to have the list of existing
symbols to select (in Config.in) and packages to provide (in .mk).
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Samuel Martin <s.martin49@gmail.com>
---
Note: a pre-rendered version of the manual with these modifications is
available at:
http://ymorin.is-a-geek.org/download/tmp/buildroot/manual/manual.html
---
docs/manual/adding-packages-directory.txt | 10 ++++++++++
docs/manual/adding-packages-virtual.txt | 6 ++++++
docs/manual/appendix.txt | 8 ++++++++
3 files changed, 24 insertions(+)
diff --git a/docs/manual/adding-packages-directory.txt b/docs/manual/adding-packages-directory.txt
index 3cf3afa..daa0eca 100644
--- a/docs/manual/adding-packages-directory.txt
+++ b/docs/manual/adding-packages-directory.txt
@@ -298,6 +298,16 @@ management, use this format:
foo needs udev /dev management and a toolchain w/ featA, featB, featC
--------------------------
+==== Dependencies on features provided by virtual packages
+
+Some features can be provided by more than one package, such as the
+openGL libraries.
+
+See xref:virtual-package-tutorial[] for more on the virtual packages.
+
+See xref:virtual-package-list[] for the symbols to depend on if your package
+depends on a feature provided by a virtual package.
+
=== The +.mk+ file
[[adding-packages-mk]]
diff --git a/docs/manual/adding-packages-virtual.txt b/docs/manual/adding-packages-virtual.txt
index 0cbe753..34563f5 100644
--- a/docs/manual/adding-packages-virtual.txt
+++ b/docs/manual/adding-packages-virtual.txt
@@ -83,6 +83,9 @@ On line 3, we select +BR2_PACKAGE_HAS_SOMETHING_VIRTUAL+, and on line 11, we
set the value of +BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL+ to the name of the
provider, but only if it is selected.
+See xref:virtual-package-list[] for the symbols to select if you implement
+a new provider for an existing virtual package.
+
==== Provider's +.mk+ file
The +.mk+ file should also declare an additional variable
@@ -96,6 +99,9 @@ packages it is an implementation of:
Of course, do not forget to add the proper build and runtime dependencies for
this package!
+See xref:virtual-package-list[] for the names of virtual packages to provide
+if you implement a new provider for an existing virtual package.
+
==== Notes on depending on a virtual package
When adding a package that requires a certain +FEATURE+ provided by a virtual
diff --git a/docs/manual/appendix.txt b/docs/manual/appendix.txt
index 35328c6..3f95551 100644
--- a/docs/manual/appendix.txt
+++ b/docs/manual/appendix.txt
@@ -14,6 +14,14 @@ include::makeusers-syntax.txt[]
include::package-list.txt[]
+[[virtual-package-list]]
+== List of virtual packages
+
+These are the virtual packages known to +Buildroot+, with the
+corresponding symbols and providers.
+
+include::virtual-package-list.txt[]
+
[[host-package-list]]
== List of host utilities available in Buildroot
--
1.8.3.2
^ permalink raw reply related [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 11/11 RFC] docs/manual: add the virtual packages list
2014-05-29 20:38 ` [Buildroot] [PATCH 11/11 RFC] docs/manual: add the virtual packages list Yann E. MORIN
@ 2014-05-31 21:25 ` Samuel Martin
0 siblings, 0 replies; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:25 UTC (permalink / raw)
To: buildroot
Yann, all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Add the list of virtual packages as an appendix to the manual.
>
> Also reference this list from appropriate locations elsewhere in
> the manual:
>
> - in section 7.2.2. "Config.in file", after the existing explanations
> on dependencies on target and toolchain options, a linux kernel, and
> udev /dev management,
>
> - in section 7.2.10. "Infrastructure for virtual packages", in the
> provider Config.in and .mk explanations, to have the list of existing
> symbols to select (in Config.in) and packages to provide (in .mk).
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Samuel Martin <s.martin49@gmail.com>
Acked-by: Samuel Martin <s.martin49@gmail.com>
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual)
2014-05-29 20:38 [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Yann E. MORIN
` (10 preceding siblings ...)
2014-05-29 20:38 ` [Buildroot] [PATCH 11/11 RFC] docs/manual: add the virtual packages list Yann E. MORIN
@ 2014-05-31 21:18 ` Samuel Martin
2014-05-31 22:45 ` Yann E. MORIN
11 siblings, 1 reply; 32+ messages in thread
From: Samuel Martin @ 2014-05-31 21:18 UTC (permalink / raw)
To: buildroot
Yann , all,
On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>
> Hello All!
>
> This series intend to add the list of virtual pacakges to the manual, for
s/intend/intends/
s/pacakges/packages/
I know you already starting fixing the typos ;)
> three reasons:
>
> - for users that are told (in a comment in the menuconfig) that a
> pacakage they need depends on a virtual pacakge, to know what provider
s/pacakge/package/g
> to select,
>
> - for people writing a new provider for an existing virtual package to
> have a reference of which symbol to select and which package to provide
> in their Config.in and .mk files,
>
> - for people writing a new package that depends on features provided by
> a virtual pacakge to know what symbol to depend on.
s/pacakge/package/
>
> The series starts with some preparatory changes and cleanups, then
> introduces a away to generate different forms of tables, then goes on by
> removing virtual packages from the current lists, and finally add a new
> list with the virtual packages.
>
> I consider this to be in RFC stage for now, especially as I would like
> some feedback on the changes I made on the Python script, changes which
> were done in an ad-hoc fashion, until it works, but will probably need
> some more love to be clean.
>
> Special thanks to Samuel for his pythonistic help! :-)
You're welcome! :-)
Regards,
--
Samuel
^ permalink raw reply [flat|nested] 32+ messages in thread* [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual)
2014-05-31 21:18 ` [Buildroot] [PATCH 0/11 RFC] Add list of virtual packages to manual (branch yem/manual) Samuel Martin
@ 2014-05-31 22:45 ` Yann E. MORIN
0 siblings, 0 replies; 32+ messages in thread
From: Yann E. MORIN @ 2014-05-31 22:45 UTC (permalink / raw)
To: buildroot
Samuel, All,
On 2014-05-31 23:18 +0200, Samuel Martin spake thusly:
> Yann , all,
>
> On Thu, May 29, 2014 at 10:38 PM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> > From: "Yann E. MORIN" <yann.morin.1998@free.fr>
> >
> > Hello All!
> >
> > This series intend to add the list of virtual pacakges to the manual, for
>
> s/intend/intends/
> s/pacakges/packages/
> I know you already starting fixing the typos ;)
Ack. I already fixed most of them, but you have a sharper eye than I do!
:-)
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
^ permalink raw reply [flat|nested] 32+ messages in thread